/************************************************************
 *
 * Alcuin: A HP48 emulator for Amiga Computer
 *
 * Copyright (c) 1995 by Stephan Schupfer <schupfer@sbox.tu-graz.ac.at>
 *
 */

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

#include <exec/exec.h>
#include <exec/types.h>
#include <exec/nodes.h>
#include <exec/tasks.h>
#include <dos/dosextens.h>
#include <workbench/workbench.h>
#include <workbench/startup.h>

#include "hp48.h"
#include "version.h"

#define OPT_DOUBLE ((BOOL)(ArgPtrs[0]))
#define OPT_COMPACT ((BOOL)(ArgPtrs[1]))
#define OPT_RESET ((BOOL)(ArgPtrs[2]))
#define OPT_INIT ((BOOL)(ArgPtrs[3]))
#define OPT_PORT1 ((STRPTR)(ArgPtrs[4]))
#define OPT_PORT2 ((STRPTR)(ArgPtrs[5]))
#define OPT_SERIAL ((STRPTR)(ArgPtrs[6]))
#define OPT_UNIT ((ULONG*)(ArgPtrs[7]))
#define OPT_XPOS ((ULONG*)(ArgPtrs[8]))
#define OPT_YPOS ((ULONG*)(ArgPtrs[9]))
#define OPT_FASTGRAPH ((BOOL)(ArgPtrs[10]))
#define OPT_HELP ((BOOL)(ArgPtrs[11]))

struct DiskObject *dobj;
char *romFileName="Alcuin_ROM\0";
char *homeDirectory="Alcuin:\0";
char *progname;

char *Copyright="Alcuin V%s\n\n© 1996 Stephan Schupfer\n\
email: schupfer@sbox.tu-graz.ac.at\n\
WWW: http://www.sbox.tu-graz.ac.at/home/schupfer/\n\n\
%s\0";
char *regist="Unregistered Version\nPlease pay the shareware fee !\0";
char *Usage="\nAlcuin: Copyright © 1996 by Stephan Schupfer\n\
--------------------------------------------\n\
Type Alcuin ? for options template\n\
Options:\n\
DOUBLE  doublesize resolution for big screens\n\
COMPACT low height keyboard layout\n\
RESET   do a reset on startup\n\
INIT    load the init-files at startup\n\
PORT1   define port1 as RAM or ROM\n\
PORT2   define port2 as RAM or ROM\n\
SERIAL  your favourite serial.device\n\
UNIT    the unit number of the serial.device\n\
XPOS    the X-position of the window\n\
YPOS    the Y-position of the window\n\
FGRAPH  use fast graphic routines (read the doc for more)\n\
HELP    this text\n\0";

char *Serial="serial.device";
int Unit=0;
int resetOnStartup=0;
int useSerial=0;
int initialize=0;
int double_res=0;
int get_port1=0;
int get_port2=0;
int compact=0;
int key=0;
int FastGraph=0;
int WinX=100;
int WinY=15;
char *versi=vers;

unsigned long	saturn_magic;
char			saturn_version;
unsigned char 	saturn_A[16];
unsigned char	saturn_B[16];
unsigned char	saturn_C[16];
unsigned char	saturn_D[16];
word_20			saturn_D0;
word_20			saturn_D1;
word_4			saturn_P;
word_20			saturn_PC;
unsigned char 	saturn_R0[16];
unsigned char	saturn_R1[16];
unsigned char 	saturn_R2[16];
unsigned char	saturn_R3[16];
unsigned char	saturn_R4[16];
unsigned char 	saturn_IN[4];
unsigned char	saturn_OUT[3];
word_1			saturn_CARRY;
word_16			saturn_ST;
word_4			saturn_HST;
word_4			saturn_hexmode;
word_20			saturn_rstk[NR_RSTK];
short			saturn_rstkp;
short			saturn_keybuf[9];
unsigned char	saturn_intenable;
unsigned char	saturn_int_pending;
unsigned char	saturn_kbd_ien;
word_4			saturn_disp_io;
word_4			saturn_contrast_ctrl;
word_8			saturn_disp_test;
word_16			saturn_crc;
word_4			saturn_power_status;
word_4			saturn_power_ctrl;
word_4			saturn_mode;
word_8			saturn_annunc;
word_4			saturn_baud;
word_4			saturn_card_ctrl;
word_4			saturn_card_status;
word_4			saturn_io_ctrl;
word_4			saturn_rcs;
word_4			saturn_tcs;
word_8			saturn_rbr;
word_8			saturn_tbr;
word_8			saturn_sreq;
word_4			saturn_ir_ctrl;
word_4			saturn_base_off;
word_4			saturn_lcr;
word_4			saturn_lbr;
word_4			saturn_scratch;
word_4			saturn_base_nibble;
word_20			saturn_disp_addr;
word_12			saturn_line_offset;
word_8			saturn_line_count;
word_16			saturn_unknown;
word_4			saturn_t1_ctrl;
word_4			saturn_t2_ctrl;
word_20			saturn_menu_addr;
word_8			saturn_unknown2;
char 			saturn_timer1;
word_32			saturn_timer2;
long			saturn_t1_instr;
long			saturn_t2_instr;
short			saturn_t1_tick;
short			saturn_t2_tick;
long			saturn_i_per_s;
short			saturn_bank_switch;
int				saturn_mem[NR_MCTL];
long			saturn_base[NR_MCTL];
long			saturn_size[NR_MCTL];
unsigned char	*saturn_bank1;
unsigned char	*saturn_bank2;
unsigned char	*saturn_rom;
unsigned char	*saturn_ram;
unsigned char	*saturn_port1;
unsigned char	*saturn_port2;

/***************************************************************/
void get_commandline()
{
struct RDArgs *Args;
LONG ArgPtrs[12]={0};
char fname[100];

if(Args = (struct RDArgs *)ReadArgs("DOUBLE/S,COMPACT/S,RESET/S,INIT/S,P1=PORT1/K,P2=PORT2/K,SER=SERIAL/K,U=UNIT/N,X=XPOS/N,Y=YPOS/N,HELP/S",ArgPtrs,NULL)) {
	if(OPT_DOUBLE) double_res=1;
	if(OPT_COMPACT) compact=1;
	if(OPT_RESET) resetOnStartup=1;
	if(OPT_INIT) initialize=1;
	if(OPT_PORT1) {
		if (!(strcmp(OPT_PORT1,"ROM"))) get_port1=1;
		if (!(strcmp(OPT_PORT1,"RAM"))) get_port1=2;
		}
	if(OPT_PORT2) {
		if (!(strcmp(OPT_PORT2,"ROM"))) get_port2=1;
		if (!(strcmp(OPT_PORT2,"RAM"))) get_port2=2;
		}
	if(OPT_SERIAL) strcpy(Serial,OPT_SERIAL);
	if(OPT_UNIT) Unit = (int)(*OPT_UNIT);
	if(OPT_XPOS) WinX = (int)(*OPT_XPOS);
	if(OPT_YPOS) WinY = (int)(*OPT_YPOS);
	if(OPT_FASTGRAPH) FastGraph=1;
	if(OPT_HELP) {
		puts(Usage);
		FreeArgs(Args);
		exit(0);
		}
	}
FreeArgs(Args);
dobj=(struct DiskObject *)GetDiskObjectNew(fname);
}

/***************************************************************/
void get_tooltypes()
{
char fname[100];
char *ttype;

strcpy(fname,homeDirectory);
strcat(fname,progname);
if (dobj=(struct DiskObject *)GetDiskObjectNew(fname)) {
	if (ttype=(char *)FindToolType(dobj->do_ToolTypes,"DOUBLE_SIZE"))
		double_res=1;
	if (ttype=(char *)FindToolType(dobj->do_ToolTypes,"PORT1")) {
		if (!(strcmp(ttype,"ROM"))) get_port1=1;
		if (!(strcmp(ttype,"RAM"))) get_port1=2;
		}
	if (ttype=(char *)FindToolType(dobj->do_ToolTypes,"PORT2")) {
		if (!(strcmp(ttype,"ROM"))) get_port2=1;
		if (!(strcmp(ttype,"RAM"))) get_port2=2;
		}
	if (ttype=(char *) FindToolType(dobj->do_ToolTypes,"RESET"))
		resetOnStartup=1;
	if (ttype=(char *) FindToolType(dobj->do_ToolTypes,"FASTGRAPH"))
		FastGraph=1;
	if (ttype=(char *)FindToolType(dobj->do_ToolTypes,"INITIALIZE"))
		initialize=1;	
	if (ttype=(char *)FindToolType(dobj->do_ToolTypes,"COMPACT"))
		compact=1;	
	if (ttype=(char *)FindToolType(dobj->do_ToolTypes,"SERIAL"))
		strcpy(Serial,ttype);	
	if (ttype=(char *)FindToolType(dobj->do_ToolTypes,"UNIT")) {
		if (!(strcmp(ttype,"0"))) Unit=0;
		if (!(strcmp(ttype,"1"))) Unit=1;
		if (!(strcmp(ttype,"2"))) Unit=2;
		if (!(strcmp(ttype,"3"))) Unit=3;
		}
	if (ttype=(char *)FindToolType(dobj->do_ToolTypes,"XPOS"))
		WinX=atoi(ttype);
	if (ttype=(char *)FindToolType(dobj->do_ToolTypes,"YPOS"))
		WinY=atoi(ttype);
	}
}

/***************************************************************/
void check_startup()
{
struct Process *proc;
struct ExecBase *SysBase;
struct WBStartup *WBenchMsg;

SysBase = *(struct ExecBase **)4;
proc=(struct Process *)SysBase->ThisTask;
progname=proc->pr_Task.tc_Node.ln_Name;
if (!proc->pr_CLI) {
	/*WaitPort(&(proc->pr_MsgPort));
	printf("port\n");
	WBenchMsg = (struct WBStartup *)GetMsg(&(proc->pr_MsgPort));
	printf("port\n");*/
	get_tooltypes();
	/*ReplyMsg((struct Message *)WBenchMsg);*/
	}
else {
	get_commandline();
	WBenchMsg=NULL;
	}
}

/***************************************************************/
int main()
{
/* Modified by Olivier Croquette ( ocroquette@free.fr )
		No key needed anymore
*/
/*
switch (decode()) {
	case 0:
		key=1;
		break;
	case 1:
		break;
	case 2:
		return 0;
	}
*/
key=1;
/* End of modification */

OpenUp();
check_startup();
OpenRest();
init_emulator();
OpenRestRest();
redraw_display();
emulate ();
return 0;
}

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