/*****************************************************************************
;  :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.7 2000/04/16 16:48:03 jah Exp jah $
;  :History.	18.07.98 started
;				13.12.98 immediate terminate if dump loading fails
;				02.03.00 expmem stuff added
;						 multiple memory windows
;  :Copyright.	All Rights Reserved
;  :Language.	C
;  :Tabsize.	4
;  :Translator.	SAS 6.58
****************************************************************************/

#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 <string.h>

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

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

/****************************************************************************/
/* defines																	*/
/****************************************************************************/

/****************************************************************************/
/* extern functions															*/
/****************************************************************************/

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

void	make_win_mem	(int);
void *	winmem_init		(void);
void	winmem_finit	(void);

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

/****************************************************************************/
/* static variables															*/
/****************************************************************************/

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

APTR app = NULL;				/* application */
APTR strip;					/* menu strip */
APTR win;					/* main window */

struct whddump_header	* header = NULL;
char					* term = 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;
APTR					* emem = NULL;

const char* StringHexAccept = "$0123456789abcdefABCDEF";

/****************************************************************************/
/* function declarations													*/
/****************************************************************************/

void	main2		(void);

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

struct NewMenu MenuData1[] =
{
	{ NM_TITLE, "Project"					, 0 ,0 ,0             ,(APTR)MEN_PROJECT	},
	{ NM_ITEM ,  "Open"						,"O",0 ,0             ,(APTR)MEN_OPEN		},
	{ NM_ITEM ,  NM_BARLABEL				, 0 ,0 ,0             ,(APTR)0				},
	{ 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 },
};

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

#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

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

#define btst(i,n) ((i >> n) & 1)

char * dmacon_h (void) {
	static char s[252];
	int v = custom->wdcu_regs[0x002/2];
	sprintf(s,MUIX_C MUIX_B "dmacon" MUIX_N MUIX_R "\nBlitter Busy = %d\n"
	"Blitter Zero = %d\nBlitter Priority = %d\nDMA Enable = %d\n"
	"Bitplane Enable = %d\nCopper Enable = %d\nBlitter Enable = %d\n"
	"Sprite Enable = %d\nDisk Enable = %d\nAudio 3 Enable = %d\n"
	"Audio 2 Enable = %d\nAudio 1 Enable = %d\nAudio 0 Enable = %d",
	btst(v,14),btst(v,13),btst(v,10),btst(v,9),btst(v,8),btst(v,7),btst(v,6),
	btst(v,5),btst(v,4),btst(v,3),btst(v,2),btst(v,1),btst(v,0) );
	/*printf("%ld\n",strlen(s));*/
	return s;
}

char * int_h (int v, char *s, const char *name) {
	sprintf(s,MUIX_C MUIX_B "int%s" MUIX_N MUIX_R "\nInterrupt Enable = %d\n"
	"CIA-B, Expansion = %d\nDisk = %d\nSerial full = %d\n"
	"Audio 3 = %d\nAudio 2 = %d\nAudio 1 = %d\nAudio 0 = %d\nBlitter = %d\n"
	"Vertical Blank = %d\nCopper = %d\nCIA-A, Expansion = %d\nSoft = %d\n"
	"Disk = %d\nSerial empty = %d",
	name,btst(v,14),btst(v,13),btst(v,12),btst(v,11),btst(v,10),btst(v,9),
	btst(v,8),btst(v,7),btst(v,6),btst(v,5),btst(v,4),btst(v,3),btst(v,2),
	btst(v,1),btst(v,0) );
	/*printf("%ld\n",strlen(s));*/
	return s;
}
char * intena_h (void) {
	static char s[228];
	return int_h(custom->wdcu_regs[0x01c/2],s,"ena");
}
char * intreq_h (void) {
	static char s[228];
	return int_h(custom->wdcu_regs[0x01e/2],s,"req");
}

char * sr_h (void) {
	static char s[56];
	int v = cpu->wdc_sr;
	sprintf(s,"Status Register\nT=%d S=%d M=%d I=%d X=%d N=%d Z=%d V=%d C=%d",
	(v>>14)&3,btst(v,13),btst(v,12),(v>>8)&7,btst(v,4),
	btst(v,3),btst(v,2),btst(v,1),btst(v,0) );
	/*printf("%ld\n",strlen(s));*/
	return s;
}

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

int main(int argc,char *argv[]) {

#ifdef _DCC
	onbreak(brkfunc);
#endif
#ifndef _DCC
	if (!(MUIMasterBase = OpenLibrary(MUIMASTER_NAME,MUIMASTER_VMIN))) exit(20);
#endif

	if (argc == 2) loaddump(argv[1]); else loaddump(NULL);
	if (header) {

		if (winmem_init()) {

			main2();

			freedump();
			
			winmem_finit();
		}
	}

#ifndef _DCC
	CloseLibrary(MUIMasterBase);
#endif
	exit(0);
}

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

void main2() {

	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,moreemem,moreslave,moreinfo,
		a_quit,a_restart,a_cont;
	ULONG signals;
	BOOL running = TRUE;

	app = ApplicationObject,
		MUIA_Application_Title      , "WHDLoad GCI",
		MUIA_Application_Version    , "$VER: WHDLoad GCI 1.1 (" __DATE__ ")",
		MUIA_Application_Copyright  , "©1998-2000 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,
						RegisterC(regd0,"D0:",NULL,cpu->wdc_regs[0],8),
						RegisterC(rega0,"A0:",NULL,cpu->wdc_regs[8],8),
						RegisterC(regd1,"D1:",NULL,cpu->wdc_regs[1],8),
						RegisterC(rega1,"A1:",NULL,cpu->wdc_regs[9],8),
						RegisterC(regd2,"D2:",NULL,cpu->wdc_regs[2],8),
						RegisterC(rega2,"A2:",NULL,cpu->wdc_regs[10],8),
						RegisterC(regd3,"D3:",NULL,cpu->wdc_regs[3],8),
						RegisterC(rega3,"A3:",NULL,cpu->wdc_regs[11],8),
						RegisterC(regd4,"D4:",NULL,cpu->wdc_regs[4],8),
						RegisterC(rega4,"A4:",NULL,cpu->wdc_regs[12],8),
						RegisterC(regd5,"D5:",NULL,cpu->wdc_regs[5],8),
						RegisterC(rega5,"A5:",NULL,cpu->wdc_regs[13],8),
						RegisterC(regd6,"D6:",NULL,cpu->wdc_regs[6],8),
						RegisterC(rega6,"A6:",NULL,cpu->wdc_regs[14],8),
						RegisterC(regd7,"D7:",NULL,cpu->wdc_regs[7],8),
						RegisterC(regusp,"USP:","User Stack Pointer",cpu->wdc_usp,8),
						RegisterC(regsr,"SR:",sr_h(),cpu->wdc_sr,4),
						RegisterC(regssp,"SSP:","Supervisor Stack Pointer",cpu->wdc_ssp,8),
						RegisterC(regpc,"PC:","Program Counter",cpu->wdc_pc,8),
						Child, Label2(""), Child, morecpu = SimpleButton("More"),
    					End,
					Child, VGroup, MUIA_Weight, 10,
						Child, VGroup, GroupFrameT("Custom"),
							Child, HGroup, MUIA_Group_Columns, 2,
								RegisterC(cudmacon,"dmacon:",dmacon_h(),custom->wdcu_regs[0x002/2],4),
								RegisterC(cuintena,"intena:",intena_h(),custom->wdcu_regs[0x01c/2],4),
								RegisterC(cuintreq,"intreq:",intreq_h(),custom->wdcu_regs[0x01e/2],4),
    							End,
    						Child, morecust = SimpleButton("More"),
    						End,
						Child, VGroup, GroupFrameT("Misc"),
							Child, morecias = SimpleButton("Cia's"),
							Child, moremem = SimpleButton("BaseMem"),
							ChildIf(emem), moreemem = SimpleButtonIf(emem,"ExpMem"),
							Child, moreslave = SimpleButton("Slave"),
							Child, moreinfo = SimpleButton("Info"),
							End,
						End,
					End,
    			ChildIf(term), term ? TextObject, TextFrame,
					MUIA_Background, MUII_TextBack,
					MUIA_Text_Contents, term,
					End : NULL,
				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) {

	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(moreemem,MUIM_Notify,MUIA_Pressed,FALSE,app,2,MUIM_Application_ReturnID,MAIN_MOREEMEM);
	DoMethod(moreslave,MUIM_Notify,MUIA_Pressed,FALSE,app,2,MUIM_Application_ReturnID,MAIN_MORESLAVE);
	DoMethod(moreinfo,MUIM_Notify,MUIA_Pressed,FALSE,app,2,MUIM_Application_ReturnID,MAIN_MOREINFO);

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

	set(win1,MUIA_Window_Open,TRUE);
	
/*
** Input loop...
*/

	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-2000 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(0);
				break;
			case MAIN_MOREEMEM:
				if (emem) {
					make_win_mem(header->wdh_ExpMemLog);
				}
				break;
			case MAIN_MORESLAVE:
				make_win_mem(header->wdh_SlaveLog);
				break;
			case MAIN_MOREINFO:
				make_win_info();
				break;
		}
		if (running && signals) Wait(signals);
	}

	set(win1,MUIA_Window_Open,FALSE);

/*
** Shut down...
*/

	MUI_DisposeObject(app);

	}
}

