/*
	WinSTon
*/

#include "..\includes\winston.h"
#include "..\includes\debug.h"
#include "..\includes\debugger.h"
#include "..\includes\debuggerbrk.h"
#include "..\includes\debuggerdisass.h"
#include "..\includes\debuggerregisters.h"
#include "..\includes\debuggertab.h"
#include "..\includes\debuggertabmemory.h"
#include "..\includes\debuggertabmfp.h"
#include "..\includes\debuggertabikbd.h"
#include "..\includes\decode.h"
#include "..\includes\dialog.h"
#include "..\includes\disass.h"
#include "..\includes\file.h"
#include "..\includes\ikbd.h"
#include "..\includes\int.h"
#include "..\includes\m68000.h"
#include "..\includes\misc.h"
#include "..\includes\mfp.h"
#include "..\includes\screen.h"
#include "..\includes\stmemory.h"
#include "..\includes\view.h"
#include "..\includes\video.h"

#ifdef USE_DEBUGGER

#define	NUM_LISTBOX_INSTRUCTIONS	128
#define	LISTBOX_BOTTOMVIEW			(NUM_LISTBOX_INSTRUCTIONS/2)
#define	LISTBOX_ENDVIEW				(NUM_LISTBOX_INSTRUCTIONS-1)

HWND DebughWnd;
PROC lpfnDlgProc;
unsigned long ListBoxAddresses[NUM_LISTBOX_INSTRUCTIONS] = { BRK_DISABLED };
unsigned long MemoryView=0;
unsigned long RunToAddress=BRK_DISABLED;
unsigned long InstructionBreakpoint=BRK_DISABLED;
unsigned long OldPC;
int InstructionTypeCopy;
BOOL RunInSlowMotion = FALSE;
BOOL RunningDecodeLoop = FALSE;							// Is running code? Hold menu input

BOOL PASCAL DebugDlgProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam);
void CreateOutputDisassemblyDialog();
void CreateOutputMemoryDialog();
void CreateInstructionBreakpointDialog();
//void CreateAddressBreakpointDialog();
void ViewLogFile(void);
void WriteDisassemblyToFile(HWND hWnd,unsigned long StartAddress,unsigned long EndAddress,char *FileName);
void WriteMemoryToFile(HWND hWnd,unsigned long StartAddress,unsigned long EndAddress,char *FileName);

typedef struct {
	char FileName[2048];
	char StartAddress[1024];
	char EndAddress[1024];
} OUTPUTDISASSEMBLY_DIALOG;

typedef struct {
	char FileName[2048];
	char StartAddress[1024];
	char EndAddress[1024];
} OUTPUTMEMORY_DIALOG;

OUTPUTDISASSEMBLY_DIALOG OutputDisassemblyDialog;
OUTPUTMEMORY_DIALOG OutputMemoryDialog;

HICON RedDotIcon,CursorIcon;
HBRUSH HighlightBrush;
int DisassembleListBoxTabs[] = { 0,90,300 };

//#define DEBUGGER_MEMORY
//#define DEBUGGER_MFP
#define DEBUGGER_ALL

//-----------------------------------------------------------------------
/*
	Create debugger modeless dialog
*/
void Debugger_Init(void)
{
	// Set default breakpoints
	Debugger_Brk_Init();

	// Fill  in structures
	strcpy(OutputDisassemblyDialog.FileName,"disass.txt");
	strcpy(OutputDisassemblyDialog.StartAddress,"00000000");
	strcpy(OutputDisassemblyDialog.EndAddress,"00000000");

	strcpy(OutputMemoryDialog.FileName,"memory.txt");
	strcpy(OutputMemoryDialog.StartAddress,"00000000");
	strcpy(OutputMemoryDialog.EndAddress,"00000000");

	// Open debugging dialog
	lpfnDlgProc = MakeProcInstance((PROC)DebugDlgProc,hInst);
//	CreateDialogParam(hInst,MAKEINTRESOURCE(IDD_DIALOG1),NULL,(DLGPROC)lpfnDlgProc,NULL); 
#ifdef DEBUGGER_MEMORY
	CreateDialogParam(hInst,MAKEINTRESOURCE(IDD_DIALOG_DEBUGGER_MEMORY),NULL,(DLGPROC)lpfnDlgProc,NULL); 
#endif
#ifdef DEBUGGER_MFP
	CreateDialogParam(hInst,MAKEINTRESOURCE(IDD_DIALOG_DEBUGGER_MFP),NULL,(DLGPROC)lpfnDlgProc,NULL); 
#endif
#ifdef DEBUGGER_ALL
	CreateDialogParam(hInst,MAKEINTRESOURCE(IDD_DIALOG_DEBUGGER),NULL,(DLGPROC)lpfnDlgProc,NULL); 
#endif
}

//-----------------------------------------------------------------------
/*
	Free debugger dialog
*/
void FreeDebugDialog()
{
	FreeProcInstance(lpfnDlgProc);
}

void SetInstructionBreakpoint(unsigned long Address)
{
	char TmpStr[256];

	// Set/clear list box, and set breakpoint accordingly
	if (Address==BRK_DISABLED) {
		Address = InstructionBreakpoint;
		InstructionBreakpoint = BRK_DISABLED;
		sprintf(TmpStr,"Breakpoint removed");
	}
	else {
		InstructionBreakpoint = Address;
		sprintf(TmpStr,"Breakpoint set at address %X",InstructionBreakpoint);
	}

	// Show to user
	SetDebuggerInfoBar(TmpStr);
}

void ToggleInstructionBreakpoint(unsigned long Address)
{
	if (InstructionBreakpoint==Address)					// Clear breakpoint
		SetInstructionBreakpoint(BRK_DISABLED);
	else {
		SetInstructionBreakpoint(BRK_DISABLED);			// Clear old
		SetInstructionBreakpoint(Address);				// And set new
	}

	// Update debugger
	SetDebuggerDisassembly(PC,FALSE);
}

//-----------------------------------------------------------------------
/*
	Debugger dialog message handler
*/
BOOL PASCAL DebugDlgProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
	char TmpStr[256];
	static HMENU hMenu;
	POINT Point,ListPoint;
	unsigned long Address;
	LONG Ret;

	switch(Message) {
		case WM_INITDIALOG:
			DebughWnd = hWnd;							// Store handle so can access anywhere!
			// Load pop-up menu for right click activate
			hMenu = LoadMenu(hInst,MAKEINTRESOURCE(IDR_MENU_POPUP));
			hMenu = GetSubMenu(hMenu,0);

			// Load icons, create brushes for drawing
			RedDotIcon = LoadIcon(hInst,MAKEINTRESOURCE(IDI_ICON2));
			CursorIcon = LoadIcon(hInst,MAKEINTRESOURCE(IDI_ICON3));
			HighlightBrush = CreateSolidBrush(RGB(0,0,128));

			// Fill items
			Debugger_Disass_Init(hWnd);
			Debugger_Registers_Init(hWnd);

			SetDebuggerDisassembly(PC,TRUE);
			Debugger_Tab_Update(DebughWnd);
			// Tab Box
			Debugger_Tab_Init(hWnd);
			return(TRUE);

		case WM_VSCROLL:
			MessageBeep(0);
			break;

		case WM_DRAWITEM:
			// Fill in disassembly listbox item
			switch(wParam) {
				case IDC_LIST_DISASS:
					break;

				case IDC_DISASS_LISTVIEW:
					Debugger_Disass_Draw((DRAWITEMSTRUCT *)lParam);
					break;
				case IDC_TABMEMORY_LISTVIEW:
					Debugger_TabMemory_Draw((DRAWITEMSTRUCT *)lParam);
					break;
				case IDC_TABIKBD_LISTVIEW:
					Debugger_TabIKBD_Draw((DRAWITEMSTRUCT *)lParam);
					break;
			}
			return(FALSE);

		case WM_CONTEXTMENU:
			if (RunningDecodeLoop)
				return(FALSE);
			if (GetDlgItem(hWnd,IDC_DISASS_LISTVIEW)==(HWND)wParam) {
				// Get screen position where clicked
				GetCursorPos(&Point);
				// Bring up menu after made selection
				TrackPopupMenu(hMenu,0,Point.x,Point.y,0,hWnd,NULL);
			}
			break;

		case WM_NOTIFY:
			// Did choose 'Tab' control?
			if (((NMHDR *)lParam)->idFrom==IDC_DEBUG_TAB) {
				if (((NMHDR *)lParam)->code==TCN_SELCHANGE) {
					// Show this Tab, and hide all others
					Debugger_Tab_ShowTab(hWnd,TabCtrl_GetCurSel(GetDlgItem(hWnd,IDC_DEBUG_TAB)));
				}
			}
			break;

		case WM_COMMAND:
			if (RunningDecodeLoop) {
				if (LOWORD(wParam)==ID_STOPEXECUTION) {
					RunSingleInstruction(BREAK_EXECUTION,NULL);	// This will stop after next instruction
					return(TRUE);
				}
				return(FALSE);
			}
			else {
				// Did change 'memory' edit box? Update listbox entries
				if (HIWORD(wParam)==EN_CHANGE) {
					if (LOWORD(wParam)==IDC_TABMEMORY_EDIT) {
						// Read address
						SendDlgItemMessage(DebughWnd,IDC_TABMEMORY_EDIT,WM_GETTEXT,256,(LONG)TmpStr);
						Address = 0;
						sscanf(TmpStr,"%X",&Address);
						Debugger_TabMemory_SetAddress(Address);
					}
					else if (LOWORD(wParam)==IDC_DISASS_EDIT) {
						// Read address
						SendDlgItemMessage(DebughWnd,IDC_DISASS_EDIT,WM_GETTEXT,256,(LONG)TmpStr);
						Address = 0;
						sscanf(TmpStr,"%X",&Address);
						Debugger_Disass_SetAddress(Address);
					}
				}
				else {
					switch(LOWORD(wParam)) {
						case ID_BREAKONNEXT:
							return(TRUE);
						case ID_SETBREAKPOINT:
							ToggleInstructionBreakpoint(Debugger_Disass_GetHighlightAddress());
							return(TRUE);
						case ID_CURRENTBREAKPOINT:
							return(TRUE);
	
						case ID_RUN:
							RunSingleInstruction(RUN_INSTRUCTION,NULL);
							return(TRUE);
						case ID_SINGLESTEP:
							RunSingleInstruction(SINGLESTEP_INSTRUCTION,NULL);						
							return(TRUE);
						case ID_STEPOVER:
							RunSingleInstruction(STEPOVER_INSTRUCTION,NULL);
							return(TRUE);
						case ID_RUNTO:
							RunSingleInstruction(RUN_TOINSTRUCTION,Debugger_Disass_GetHighlightAddress());
							return(TRUE);

						case ID_LOADDISCIMAGE:
							M68000_OutputHistory();
							return(TRUE);

						case ID_EXECUTION_SLOWMOTION:
							RunInSlowMotion ^= TRUE;

							return(TRUE);
						case ID_EXIT:
							DestroyWindow(::hWnd);
							return(TRUE);

						case ID_OUTPUT_DISASSEMBLY:
							CreateOutputDisassemblyDialog();
							return(TRUE);
						case ID_USELOGFILE:
							return(TRUE);
						case ID_VIEWLOGFILE:
							ViewLogFile();
							return(TRUE);

						case ID_INSTRUCTIONBREAK:
							CreateInstructionBreakpointDialog();
							return(TRUE);
						case ID_ADDRESSBREAK:
							Debugger_Brk_Dialog();
//							CreateAddressBreakpointDialog();
							return(TRUE);
					}
				}
			}
			break;
	}

	return(FALSE);
}

//-----------------------------------------------------------------------
/*
*/
BOOL PASCAL DiassemblyDlgProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
	unsigned long StartAddress,EndAddress;

	switch(Message) {
		case WM_INITDIALOG:
			// Set dialog items
			SetDlgItemText(hWnd,IDC_EDIT_DISFILENAME,OutputDisassemblyDialog.FileName);
			SetDlgItemText(hWnd,IDC_EDIT_DISSTART,OutputDisassemblyDialog.StartAddress);
			SetDlgItemText(hWnd,IDC_EDIT_DISEND,OutputDisassemblyDialog.EndAddress);
			return(TRUE);

		
		case WM_COMMAND:
			switch(wParam) {
				case ID_DISBROWSE:
					File_OpenSelectDlg(hWnd,OutputDisassemblyDialog.FileName,FALSE,FALSE,TRUE);
					return(TRUE);

				case IDOK:
					// Read back dialog items
					GetDlgItemText(hWnd,IDC_EDIT_DISFILENAME,OutputDisassemblyDialog.FileName,1024);
					GetDlgItemText(hWnd,IDC_EDIT_DISSTART,OutputDisassemblyDialog.StartAddress,1024);
					GetDlgItemText(hWnd,IDC_EDIT_DISEND,OutputDisassemblyDialog.EndAddress,1024);
					// Find start/end addresses
					StartAddress = EndAddress = 0;
					sscanf(OutputDisassemblyDialog.StartAddress,"%X",&StartAddress);
					sscanf(OutputDisassemblyDialog.EndAddress,"%X",&EndAddress);
					// Write out file
					WriteDisassemblyToFile(hWnd,StartAddress,EndAddress,OutputDisassemblyDialog.FileName);

				case IDCANCEL:
					EndDialog(hWnd,0);
					return(TRUE);
				}
			break;
	}

	return(FALSE);
}

//-----------------------------------------------------------------------
/*
	Create output disassembly dialog
*/
void CreateOutputDisassemblyDialog()
{
	PROC lpfnDlgProc;

	// Open debugging dialog
	lpfnDlgProc = MakeProcInstance((PROC)DiassemblyDlgProc,hInst);
	DialogBoxParam(hInst,MAKEINTRESOURCE(IDD_DIALOG3),NULL,(DLGPROC)lpfnDlgProc,NULL);
}

//-----------------------------------------------------------------------
/*
	Set/Clear instruction breakpoint at address, default to PC
*/
BOOL PASCAL InstructionBreakpointDlgProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
	char TmpStr[256];
	unsigned long Address;

	switch(Message) {
		case WM_INITDIALOG:
			// Set default entry in dialog
			if (InstructionBreakpoint==BRK_DISABLED)
				sprintf(TmpStr,"%X",PC);
			else
				sprintf(TmpStr,"%X",InstructionBreakpoint);
			SetDlgItemText(hWnd,IDC_EDIT_INSBREAKPOINT,TmpStr);
			return(FALSE);

		case WM_COMMAND:
			switch(wParam) {
				case IDOK:
					// Find hex address entered into dialog
					GetDlgItemText(hWnd,IDC_EDIT_INSBREAKPOINT,TmpStr,256);
					Address = 0;
					sscanf(TmpStr,"%X",&Address);
					// And set/clear breakpoint
					ToggleInstructionBreakpoint(Address);

				case IDCANCEL:
					EndDialog(hWnd,0);
					return(TRUE);
				}
			break;
	}

	return(FALSE);
}

//-----------------------------------------------------------------------
/*
	Create dialog for entering instruction breakpoint address
*/
void CreateInstructionBreakpointDialog()
{
	PROC lpfnDlgProc;

	// Open debugging dialog
	lpfnDlgProc = MakeProcInstance((PROC)InstructionBreakpointDlgProc,hInst);
	DialogBoxParam(hInst,MAKEINTRESOURCE(IDD_DIALOG2),NULL,(DLGPROC)lpfnDlgProc,NULL);
}

//-----------------------------------------------------------------------
/*
	Set/Clear address breakpoint
*/
/*
BOOL PASCAL AddressBreakpointDlgProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
	char TmpStr[256];
	unsigned long Address;

	switch(Message) {
		case WM_INITDIALOG:
			// Set default entry in dialog
			sprintf(TmpStr,"%X",AddressBreakpoint);
			SetDlgItemText(hWnd,IDC_EDIT_INSBREAKPOINT,TmpStr);
			return(FALSE);

		case WM_COMMAND:
			switch(wParam) {
				case IDOK:
					// Find hex address entered into dialog
					GetDlgItemText(hWnd,IDC_EDIT_INSBREAKPOINT,TmpStr,256);
					Address = 0;
					sscanf(TmpStr,"%X",&Address);
					// And set/clear breakpoint
					if (Address==BRK_DISABLED)
						AddressBreakpoint = BRK_DISABLED;
					else
						AddressBreakpoint = Address&0xffffff;

				case IDCANCEL:
					EndDialog(hWnd,0);
					return(TRUE);
				}
			break;
	}

	return(FALSE);
}
*/

//-----------------------------------------------------------------------
/*
	Create dialog for entering address breakpoint address
*/
/*
void CreateAddressBreakpointDialog()
{
	PROC lpfnDlgProc;

	// Open debugging dialog
	lpfnDlgProc = MakeProcInstance((PROC)AddressBreakpointDlgProc,hInst);
	DialogBoxParam(hInst,MAKEINTRESOURCE(IDD_DIALOG9),NULL,(DLGPROC)lpfnDlgProc,NULL);
}
*/

//-----------------------------------------------------------------------
/*
	Run 'notepad' to view log file
*/
void ViewLogFile(void)
{
}

//-----------------------------------------------------------------------
/*
	Write out disassembly to file
*/
void WriteDisassemblyToFile(HWND hWnd,unsigned long StartAddress,unsigned long EndAddress,char *FileName)
{
	ofstream out;
	char TmpStr[256],DisassLine[256];
	unsigned long Length;
	unsigned long StartPC;

	// Find 'length' of data to output, return is not valid
	Length = EndAddress-StartAddress;
	if (Length<=0)
		return;

	// Create our output file
	out.open(FileName);
	if (out) {
		DisPC = StartAddress;								// Start from here
		while(DisPC<=EndAddress) {
			StartPC = DisPC;
			Disass_DiassembleLine();								// Disassemble instruction
			sprintf(TmpStr,"%8.8X   %s",StartPC,szOpData);	// Build string
			Misc_PadStringWithSpaces(TmpStr,35);					// Use spaces rather than tabs
			sprintf(DisassLine,"%s%s",TmpStr,szOpString);
			out << DisassLine << endl;						// and save to file
		}

		out.close();										// Close up

		sprintf(TmpStr,"File '%s' written.",FileName);
		WinSTon_SysError(TmpStr,PROG_NAME);
	}
	else {
		sprintf(TmpStr,"Unable to create file '%s'.",FileName);
		WinSTon_SysError(TmpStr,"Debugger Error!");
	}
}

//-----------------------------------------------------------------------
/*
	Write out memory to file
*/
void WriteMemoryToFile(HWND hWnd,unsigned long StartAddress,unsigned long EndAddress,char *FileName)
{
	ofstream out;
	char TmpStr[256];
	unsigned long *LongPtr;
	unsigned char *CharPtr;
	unsigned long Mem[4];
	unsigned char Chars[16];
	unsigned long Length,ViewAddress;
	int j;

	// Find 'length' of data to output, return is not valid
	Length = EndAddress-StartAddress;
	if (Length<=0)
		return;

	// Create our output file
	out.open(FileName);
	if (out) {
		ViewAddress = StartAddress;

		// Disassemble istruction
		while(ViewAddress<=EndAddress) {
			LongPtr = (unsigned long *)((unsigned long)STRam+ViewAddress);
			// Copy 'longs' of memory into array for display
			for(j=0; j<4; j++)
				Mem[j] = STMemory_Swap68000Long(*LongPtr++);
			// Copy characters
			CharPtr = (unsigned char *)((unsigned long)STRam+ViewAddress);
			for(j=0; j<16; j++) {
				Chars[j] = *CharPtr++;
				// Is char valid? if show a space
				if ( (Chars[j]<32) || (Chars[j]==127) )
					Chars[j] = ' ';
			}

			// Create string to write to listbox 'addr:hex data:chars'
			sprintf(TmpStr,"%8.8X\t\t%8.8X\t%8.8X\t%8.8X\t%8.8X\t\t%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c"
			,ViewAddress,Mem[0],Mem[1],Mem[2],Mem[3]
			,Chars[0],Chars[1],Chars[2],Chars[3],Chars[4],Chars[5],Chars[6],Chars[7]
			,Chars[8],Chars[9],Chars[10],Chars[11],Chars[12],Chars[13],Chars[14],Chars[15] );

			// Save to file
			out << TmpStr << endl;

			// Increment address
			ViewAddress += SIZE_LONG*4;
		}

		out.close();										// Close up

		sprintf(TmpStr,"File '%s' written.",FileName);
		WinSTon_SysError(TmpStr,PROG_NAME);
	}
	else {
		sprintf(TmpStr,"Unable to create file '%s'.",FileName);
		WinSTon_SysError(TmpStr,"Debugger Error!");
	}
}

//-----------------------------------------------------------------------
/*
	Set debugger disassembly
*/
void SetDebuggerDisassembly(unsigned long ViewAddress,BOOL FullRefresh)
{
	Debugger_Disass_SetHighlightAddress(ViewAddress);
}

//-----------------------------------------------------------------------
/*
	Set text in debugger status bar
*/
void SetDebuggerInfoBar(char *InfoString)
{
	SetDlgItemText(DebughWnd,IDC_INFOBAR,InfoString);
}

//-----------------------------------------------------------------------
/*
	For single-step, generate interrupt after one instruction and
	set breakpoint to stop execution
*/
NAKED void InterruptHandler_SingleStep(void)
{
	SAVE_ASSEM_REGS										// Save assembly registers

	// Remove this interrupt from list and re-order
	Int_AcknowledgeInterrupt();

	RESTORE_ASSEM_REGS									// Restore assembly registers
	__asm {
		mov		ebx,esi
		sub		ebx,STRAM_OFFSET						// As ST address space
		and		ebx,0xffffff
		mov		[BreakPointInstruction],ebx				// Store PC to breakpoint, will stop now
		ret
	}
}

//-----------------------------------------------------------------------
/*
	Need to execute window message handler more when in debugger as need to break out
	of instruction decoding loop
*/
void InterruptHandler_Debugger_Execute(void)
{
	// Remove this interrupt from list and re-order
	Int_AcknowledgeInterrupt();
	// Set up next VBL
	Int_AddAbsoluteInterrupt(CYCLES_DEBUGGER,INTERRUPT_DEBUGGER);

	// And handle any windows messages, check for quit message
	if (WinSTon_RunWindowsMessageHandler())
		BreakPointInstruction = BRK_STOP;				// Quit out on next instruction
}

NAKED void InterruptHandler_Debugger(void)
{
	SAVE_ASSEM_REGS										// Save assembly registers
	
	InterruptHandler_Debugger_Execute();

	RESTORE_ASSEM_REGS									// Restore assembly registers
	__asm	ret
}

//-----------------------------------------------------------------------
/*
	Run single instruction or until breakpoint
*/
void RunSingleInstruction(int InstructionType,unsigned long RunToAddress)
{
	char TmpStr[256];
	unsigned short int *Ptr;
	unsigned short int OpCode;

	InstructionTypeCopy = InstructionType;
	OldPC = PC;
	// Run instructions, until check break
	switch (InstructionType) {
		case RUN_INSTRUCTION:
			BreakPointInstruction = InstructionBreakpoint;
			SetDebuggerInfoBar("Running...");
			break;

		case BREAK_EXECUTION:
			// Add break to occur now
			BreakPointInstruction = BRK_STOP;
			return;
		case SINGLESTEP_INSTRUCTION:
			// Set break to occur AFTER next instruction
			BreakPointInstruction = BRK_SINGLE_INSTRUCTION;
			break;
		case RUN_TOINSTRUCTION:
			BreakPointInstruction = RunToAddress&0xffffff;
			break;
	}

	// Run instructions until break
	RunningDecodeLoop = TRUE;
	RunIntructions();
	RunningDecodeLoop = FALSE;

	sprintf(TmpStr,"");
	switch (InstructionTypeCopy) {
		case SINGLESTEP_INSTRUCTION:
			break;
		case BREAK_EXECUTION:
			sprintf(TmpStr,"Execution stopped at address %X.",PC);
			break;
		case STEPOVER_INSTRUCTION:
			sprintf(TmpStr,"Skipped instruction at address %X.",PC);
			break;

		default:
			sprintf(TmpStr,"Breakpoint reached at address %X. Execution stopped",PC);
	}
	SetDebuggerInfoBar(TmpStr);

	// And update(put mouse back!)
	View_ToggleWindowsMouse(MOUSE_WINDOWS);
	Screen_Draw();
	Debugger_Registers_Update(DebughWnd);
	// If single step or skip update same window
	if ( (InstructionType==SINGLESTEP_INSTRUCTION) || (InstructionType==STEPOVER_INSTRUCTION) ) {
		SetDebuggerDisassembly(PC,FALSE);
		Debugger_Tab_Update(DebughWnd);
	}
	else {
		SetDebuggerDisassembly(PC,TRUE);
		Debugger_Tab_Update(DebughWnd);
	}
}

#endif	//USE_DEBUGGER
