/*****************************************************************************
;  :Module.		WHDLoadGCI.c
;  :Author.		Bert Jahn
;  :EMail.		jah@fh-zwickau.de
;  :Address.	Franz-Liszt-Straße 16, Rudolstadt, 07404, Germany
;  :Version.	$Id: WHDloadGCI.c 0.2 1998/12/13 23:35:08 jah Exp jah $
;  :History.	18.07.98 started
;				13.12.98 immediate terminate if dump loading fails
;  :Copyright.	All Rights Reserved
;  :Language.	C
;  :Tabsize.	4
;  :Translator.	SAS 6.58
****************************************************************************/

#include <mui/HexEdit_mcc.h>

#include <clib/alib_protos.h>
#include <clib/exec_protos.h>
#include <clib/gadtools_protos.h>
#include <clib/muimaster_protos.h>

#include <pragmas/muimaster_pragmas.h>

#include <stdio.h>
#include <stdlib.h>

#include "whddump.h"
#include "WHDLoadGCI.h"

/****************************************************************************/

void	make_win_cpu	(void);
void	make_win_cust	(void);

void	freedump	(void);
BOOL	loaddump	(STRPTR name);

/****************************************************************************/

extern struct Library *SysBase,*DOSBase;
struct Library *MUIMasterBase;

APTR app,strip,win,
	win_mem=NULL;

APTR regmsp,regcacr,regpcr,regbuscr;

struct whddump_header	* header = NULL;
struct whddump_cpu		* cpu = NULL;
struct whddump_custom	* custom = NULL;
struct whddump_cia		* ciaa = NULL;
struct whddump_cia		* ciab = NULL;
APTR					* slave = NULL;
APTR					* mem = NULL;

/****************************************************************************/

static VOID fail(APTR app,char *str) {
	if (app) MUI_DisposeObject(app);
#ifndef _DCC
	if (MUIMasterBase) CloseLibrary(MUIMasterBase);
#endif
	if (str) {
		puts(str);
		exit(20);
	}
	exit(0);
}

#ifdef _DCC
int brkfunc(void) { return(0); }
int wbmain(struct WBStartup *wb_startup) {
	extern int main(int argc, char *argv[]);
	return (main(0, (char **)wb_startup));
}
#endif

#ifdef __SASC
int CXBRK(void) { return(0); }
int _CXBRK(void) { return(0); }
void chkabort(void) {}
#endif

static VOID init(VOID) {
#ifdef _DCC
	onbreak(brkfunc);
#endif
#ifndef _DCC
	if (!(MUIMasterBase = OpenLibrary(MUIMASTER_NAME,MUIMASTER_VMIN)))
	fail(NULL,"Failed to open "MUIMASTER_NAME".");
#endif
}

/****************************************************************************/

struct NewMenu MenuData1[] =
{
	{ NM_TITLE, "Project"					, 0 ,0 ,0             ,(APTR)MEN_PROJECT	},
	{ NM_ITEM ,  "About"					,"?",0 ,0             ,(APTR)MEN_ABOUT		},
	{ NM_ITEM ,  "About MUI"				,"M",0 ,0             ,(APTR)MEN_ABOUTMUI	},
	{ NM_ITEM ,  NM_BARLABEL				, 0 ,0 ,0             ,(APTR)0				},
	{ NM_ITEM ,  "Quit"						,"Q",0 ,0             ,(APTR)MEN_QUIT		},

	{ NM_END,NULL,0,0,0,(APTR)0 },
};

const char* StringHexAccept = "$0123456789abcdefABCDEF";

/*
 *	create string for "String"
 */
STRPTR val2hex4(UWORD val) {
	static char s[6];
	if (val < 16) {
		sprintf(s,"%d",val);
	} else {
		sprintf(s,"$%x",val);
	}
	return s;
}
STRPTR val2hex8(ULONG val) {
	static char s[10];
	if (val < 16) {
		sprintf(s,"%ld",val);
	} else {
		sprintf(s,"$%lx",val);
	}
	return s;
}
/*
 *	create string for "Text"
 */
STRPTR val2hex1t(UBYTE val) {
	static char s[3];
	sprintf(s,"\33r%ld",val);
	return s;
}
STRPTR val2hex4t(UWORD val) {
	static char s[6];
	if (val < 16) {
		sprintf(s,"\33r%d",val);
	} else {
		sprintf(s,"\33r$%x",val);
	}
	return s;
}
STRPTR val2hex8t(ULONG val) {
	static char s[10];
	if (val < 16) {
		sprintf(s,"\33r%ld",val);
	} else {
		sprintf(s,"\33r$%lx",val);
	}
	return s;
}
STRPTR val2hex16t(ULONG val1,ULONG val2) {
	static char s[18];
	if (val1) {
		sprintf(s,"\33r$%lx%08lx",val1,val2);
	} else {
		return val2hex8(val2);
	}
	return s;
}
/*
 *	set contents of "String"
 */
void sethex4(APTR gad, UWORD val) {
	set(gad,MUIA_String_Contents,val2hex4(val));
}
void sethex8(APTR gad, ULONG val) {
	set(gad,MUIA_String_Contents,val2hex8(val));
	set(gad,MUIA_Text_Contents,val2hex8(val));
}
/*
 *	set contents of "Text"
 */
void sethex1t(APTR gad, UBYTE val) {
	set(gad,MUIA_Text_Contents,val2hex1t(val));
}
void sethex4t(APTR gad, UWORD val) {
	set(gad,MUIA_Text_Contents,val2hex4t(val));
}
void sethex8t(APTR gad, ULONG val) {
	set(gad,MUIA_Text_Contents,val2hex8t(val));
}
void sethex16t(APTR gad, ULONG val1, ULONG val2) {
	set(gad,MUIA_Text_Contents,val2hex16t(val1,val2));
}

/****************************************************************************/

void make_win_mem(int address) {
	ULONG open;
	APTR strip_mem;
	APTR prop, hex;

	if (win_mem) {
		get(win_mem,MUIA_Window_Open,&open);
		if (open)	set(win_mem,MUIA_Window_Open,FALSE);
		else		set(win_mem,MUIA_Window_Open,TRUE);
	} else {
		win_mem = WindowObject,
			MUIA_Window_Title, "More Memory",
			MUIA_Window_ID   , MAKE_ID('M','E','M','0'),
			MUIA_Window_Menustrip, strip_mem = MUI_MakeObject(MUIO_MenustripNM,MenuData1,0),
			WindowContents, HGroup,
				Child, hex = HexEditObject, VirtualFrame,
					MUIA_HexEdit_LowBound, mem,
					MUIA_HexEdit_HighBound, ((UBYTE*)mem) + header->wdh_BaseMemSize - 1,
					MUIA_HexEdit_BaseAddressOffset, -(ULONG)mem,
					MUIA_HexEdit_EditMode, TRUE,
					MUIA_HexEdit_SelectMode, MUIV_HexEdit_SelectMode_Byte,
					MUIA_HexEdit_CursorAddress,address,
					MUIA_CycleChain, 1,
					End,
				Child, prop = ScrollbarObject,
					MUIA_Prop_UseWinBorder, MUIV_Prop_UseWinBorder_Right,
					End,
				End,
			End;
		if (win_mem) {
			DoMethod(app,OM_ADDMEMBER,win_mem);
			set(hex,MUIA_HexEdit_PropObject,prop);
			DoMethod(win_mem,MUIM_Notify,MUIA_Window_CloseRequest,TRUE,app,2,MUIM_Application_ReturnID,MAIN_MOREMEM);
			set(win_mem,MUIA_Window_Open,TRUE);
		} else {
			MUI_Request(app,win,0,NULL,"Ok","Couldn't open Memory window.");
		}
	}
}

/****************************************************************************/

int main(int argc,char *argv[])
{
	APTR win1;
	APTR
		regd0,regd1,regd2,regd3,regd4,regd5,regd6,regd7,
		rega0,rega1,rega2,rega3,rega4,rega5,rega6,
		regsr,regssp,regusp,regpc,morecpu,
		cudmacon,cuintena,cuintreq,morecust,
		morecias,moremem,
		a_quit,a_restart,a_cont;
	ULONG signals;
	BOOL running = TRUE;

	init();

	if (! loaddump(NULL)) return 20;

	app = ApplicationObject,
		MUIA_Application_Title      , "WHDLoad GCI",
		MUIA_Application_Version    , "$VER: WHDLoad GCI 1.0 (18.07.98)",
		MUIA_Application_Copyright  , "©1998 by Wepl",
		MUIA_Application_Author     , "Wepl",
		MUIA_Application_Description, "WHDload Visualisation and Debugging.",
		MUIA_Application_Base       , "WHDLoadGCI",
		MUIA_Application_Window, win1 = WindowObject,
			MUIA_Window_Title, "WHDLoad GCI",
			MUIA_Window_ID   , MAKE_ID('M','A','I','N'),
			MUIA_Window_Menustrip, strip = MUI_MakeObject(MUIO_MenustripNM,MenuData1,0),
			WindowContents, VGroup,
				Child, HGroup,
    				Child, HGroup, GroupFrameT("CPU"), MUIA_Group_Columns, 4, MUIA_Weight, 20,
						Child, Label2("D0:"), Child, regd0 = StringHex8,
						Child, Label2("A0:"), Child, rega0 = StringHex8,
						Child, Label2("D1:"), Child, regd1 = StringHex8,
						Child, Label2("A1:"), Child, rega1 = StringHex8,
						Child, Label2("D2:"), Child, regd2 = StringHex8,
						Child, Label2("A2:"), Child, rega2 = StringHex8,
						Child, Label2("D3:"), Child, regd3 = StringHex8,
						Child, Label2("A3:"), Child, rega3 = StringHex8,
						Child, Label2("D4:"), Child, regd4 = StringHex8,
						Child, Label2("A4:"), Child, rega4 = StringHex8,
						Child, Label2("D5:"), Child, regd5 = StringHex8,
						Child, Label2("A5:"), Child, rega5 = StringHex8,
 						Child, Label2("D6:"), Child, regd6 = StringHex8,
 						Child, Label2("A6:"), Child, rega6 = StringHex8,
 						Child, Label2("D7:"), Child, regd7 = StringHex8,
 						Child, Label2("USP:"), Child, regusp = StringHex8,
						Child, Label2("SR:"), Child, regsr = StringHex4,
  						Child, Label2("SSP:"), Child, regssp = StringHex8,
  						Child, Label2("PC:"), Child, regpc = StringHex8,
						Child, Label2(""), Child, morecpu = SimpleButton("More"),
    					End,
					Child, VGroup, MUIA_Weight, 10,
						Child, VGroup, GroupFrameT("Custom"),
							Child, HGroup, MUIA_Group_Columns, 2,
    							Child, Label2("dmacon:"), Child, cudmacon = StringHex4,
    							Child, Label2("intena:"), Child, cuintena = StringHex4,
    							Child, Label2("intreq:"), Child, cuintreq = StringHex4,
    							End,
    						Child, morecust = SimpleButton("More"),
    						End,
						Child, VGroup, GroupFrameT("Misc"),
							Child, morecias = SimpleButton("Cia's"),
							Child, moremem = SimpleButton("Memory"),
							End,
						End,
    				End,
				Child, HGroup, GroupFrameT("Actions"), MUIA_Group_SameWidth, TRUE,
					Child, a_quit = SimpleButton("Quit"),
					Child, a_restart = SimpleButton("Restart"),
					Child, a_cont = SimpleButton("Continue"),
					End,
				End,
			End,
		End;

	if (!app)
		fail(app,"Failed to create Application.");

	win = win1;

	DoMethod(win1,MUIM_Notify,MUIA_Window_CloseRequest,TRUE,app,2,MUIM_Application_ReturnID,MUIV_Application_ReturnID_Quit);

	DoMethod(morecpu,MUIM_Notify,MUIA_Pressed,FALSE,app,2,MUIM_Application_ReturnID,MAIN_MORECPU);
	DoMethod(morecust,MUIM_Notify,MUIA_Pressed,FALSE,app,2,MUIM_Application_ReturnID,MAIN_MORECUST);
	DoMethod(moremem,MUIM_Notify,MUIA_Pressed,FALSE,app,2,MUIM_Application_ReturnID,MAIN_MOREMEM);

	DoMethod(a_quit,MUIM_Notify,MUIA_Pressed,FALSE,app,2,MUIM_Application_ReturnID,MUIV_Application_ReturnID_Quit);

/*
** Input loop...
*/

	set(win1,MUIA_Window_Open,TRUE);
	
	sethex8(regd0,cpu->wdc_regs[0]);
	sethex8(regd1,cpu->wdc_regs[1]);
	sethex8(regd2,cpu->wdc_regs[2]);
	sethex8(regd3,cpu->wdc_regs[3]);
	sethex8(regd4,cpu->wdc_regs[4]);
	sethex8(regd5,cpu->wdc_regs[5]);
	sethex8(regd6,cpu->wdc_regs[6]);
	sethex8(regd7,cpu->wdc_regs[7]);
	sethex8(rega0,cpu->wdc_regs[8]);
	sethex8(rega1,cpu->wdc_regs[9]);
	sethex8(rega2,cpu->wdc_regs[10]);
	sethex8(rega3,cpu->wdc_regs[11]);
	sethex8(rega4,cpu->wdc_regs[12]);
	sethex8(rega5,cpu->wdc_regs[13]);
	sethex8(rega6,cpu->wdc_regs[14]);
	sethex8(regpc,cpu->wdc_pc);
	sethex4(regsr,cpu->wdc_sr);
	sethex8(regusp,cpu->wdc_usp);
	sethex8(regssp,cpu->wdc_ssp);
	sethex4(cudmacon,custom->wdcu_regs[0x002/2]);
	sethex4(cuintena,custom->wdcu_regs[0x01c/2]);
	sethex4(cuintreq,custom->wdcu_regs[0x01e/2]);
	
	set(cudmacon,MUIA_ShortHelp,"BlitterBusy pine = 0\nAudio 0 = 1");
	
	while (running)
	{
		ULONG id = DoMethod(app,MUIM_Application_Input,&signals);

		switch (id)
		{
			case MEN_QUIT:
			case MUIV_Application_ReturnID_Quit:
				running = FALSE;
				break;

			case MEN_ABOUT:
				MUI_Request(app,win1,0,NULL,"OK","\33cWHDLoad Graphical Coders Interface\n©1998 Wepl\nAll Rights Reserved.");
				break;
			case MEN_ABOUTMUI:
				DoMethod(app,MUIM_Application_AboutMUI,win);
				break;

			case MAIN_MORECPU:
				make_win_cpu();
    			break;
			case MAIN_MORECUST:
				make_win_cust();
				break;
			case MAIN_MOREMEM:
				make_win_mem(cpu->wdc_pc);
				break;

		}
		if (running && signals) Wait(signals);
	}

	set(win1,MUIA_Window_Open,FALSE);

/*
** Shut down...
*/

	fail(app,NULL);

	freedump();

}

