/***************************************************************
 *  Alcuin: A HP48 emulator for Amiga Computers
 * 
 *  (C) 1995 Stephan Schupfer (schupfer@sbox.tu-graz.ac.at)
 *
 */

#include <stdio.h>
#include <exec/types.h>
#include <exec/memory.h>
#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>
#include <graphics/gfxmacros.h>
#include <graphics/gfxbase.h>
#include <dos/dos.h>
#include <libraries/gadtools.h>
#include <libraries/asl.h>
#include <libraries/locale.h>
#include <utility/tagitem.h>
#include <workbench/workbench.h>

#include "A48.h"
#include "main.h"
#include "hp48.h"
#include "romio.h"
#include "lokal.h"
#include "version.h"

struct IntuitionBase *IntuitionBase;
struct GadToolsBase *GadToolsBase;
struct GfxBase *GfxBase;
struct DOSBase *DOSBase;
struct Library *AslBase,*DiskfontBase;
struct Library *IconBase,*WorkbenchBase,*LocaleBase;
struct Screen *scr;
struct Window *win;
struct RastPort *rp;
struct Menu *menu;
struct Gadget *ConT,*b[49];
struct TextFont *font;
struct MsgPort *myport;

int Vanilla[128]={
	0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x40,0xFF,
	0xFF,0xFF,0xFF,0x44,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	
	0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x8000,0xFF,0xFF,
	0xFF,0xFF,0x01,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
	0xFF,0xFF,0x20,0x00,0xFF,0x10,0x02,0x30,0x03,0x13,
	0x12,0x11,0x23,0x22,0x21,0x33,0x32,0x31,0xFF,0xFF,
	0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
	0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
	0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
	0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x14,0x84,0x83,
	0x82,0x81,0x80,0x24,0x74,0x73,0x72,0x71,0x70,0x04,
	0x64,0x63,0x62,0x61,0x60,0x34,0x54,0x53,0x52,0x51,
	0x50,0x43,0x40,0xFF,0xFF,0xFF,0xFF,0x41
	};

int But[49]={
	0x14,0x84,0x83,0x82,0x81,0x80,
	0x24,0x74,0x73,0x72,0x71,0x70,
	0x04,0x64,0x63,0x62,0x61,0x60,
	0x34,0x54,0x53,0x52,0x51,0x50,
	0x44,0x43,0x42,0x41,0x40,
	0x35,0x33,0x32,0x31,0x30,
	0x25,0x23,0x22,0x21,0x20,
	0x15,0x13,0x12,0x11,0x10,
	0x8000,0x03,0x02,0x01,0x00
	};

struct EasyStruct es={
	sizeof(struct EasyStruct),
	0,
	"Alcuin",
	NULL,
	"Okay"
	};

struct TagItem FensterTags [] = {
	{ WA_Flags, WFLG_CLOSEGADGET | WFLG_DEPTHGADGET | WFLG_DRAGBAR | WFLG_ACTIVATE | 
		WFLG_SMART_REFRESH | WFLG_NEWLOOKMENUS | WFLG_REPORTMOUSE},
	{ WA_IDCMP, IDCMP_CLOSEWINDOW | IDCMP_MENUPICK | IDCMP_VANILLAKEY | IDCMP_RAWKEY |
		IDCMP_GADGETUP },
	{ WA_Left,100 },
	{ WA_Top, 0 },
	{ WA_InnerHeight, 330 },
	{ WA_InnerWidth, 154 },
	{ WA_Gadgets, NULL },
	{ WA_Title, (ULONG) "Alcuin" },
	{ TAG_END }
	};

struct NewMenu FensterMenu[] = {
	NM_TITLE, NULL, NULL, 0, NULL, NULL,
	NM_ITEM, NULL, (STRPTR) "A", 0, 0L, NULL,
	NM_ITEM, (STRPTR)NM_BARLABEL, NULL, 0, 0L, NULL,
	NM_ITEM, NULL, (STRPTR) "H", 0, 0L, NULL,
	NM_ITEM, (STRPTR)NM_BARLABEL, NULL, 0, 0L, NULL,
	NM_ITEM, NULL, (STRPTR) "R", 0, 0L, NULL,
	NM_ITEM, (STRPTR)NM_BARLABEL, NULL, 0, 0L, NULL,
	NM_ITEM, NULL, (STRPTR) "I", 0, 0L, NULL,
	NM_ITEM, (STRPTR)NM_BARLABEL, NULL, 0, 0L, NULL,
	NM_ITEM, NULL, (STRPTR) "X", 0, 0L, NULL,
	NM_ITEM, NULL, (STRPTR) "Q", 0, 0L, NULL,
	NM_END, NULL, NULL, 0, 0L, NULL };

struct TagItem MenuTags[] = {
	{ GTMN_FrontPen, 0L },
	{ TAG_END }
	};

struct TextAttr hp_font = {
	(STRPTR)"hp48.font",9,0x00,0x00
	};
struct TextAttr hp_font_big = {
	(STRPTR)"hp48.font",13,0x00,0x00
	};

struct TagItem BoxTags[] = {
	{ GTBB_Recessed, TRUE },
	{ GTBB_FrameType, BBFT_BUTTON },
	{ GT_VisualInfo, NULL },
	{ TAG_END }
	};

struct NewGadget GXButton[49] = {
	{4,92,20,12,(UBYTE *)"",NULL,0,PLACETEXT_IN,NULL,NULL},
	{29,92,20,12,(UBYTE *)"",NULL,1,PLACETEXT_IN,NULL,NULL},
	{54,92,20,12,(UBYTE *)"",NULL,2,PLACETEXT_IN,NULL,NULL},
	{79,92,20,12,(UBYTE *)"",NULL,3,PLACETEXT_IN,NULL,NULL},
	{104,92,20,12,(UBYTE *)"",NULL,4,PLACETEXT_IN,NULL,NULL},
	{129,92,20,12,(UBYTE *)"",NULL,5,PLACETEXT_IN,NULL,NULL},
	{4,119,20,12,(UBYTE *)"MTH",&hp_font,6,PLACETEXT_IN,NULL,NULL},
	{29,119,20,12,(UBYTE *)"PRG",&hp_font,7,PLACETEXT_IN,NULL,NULL},
	{54,119,20,12,(UBYTE *)"CST",&hp_font,8,PLACETEXT_IN,NULL,NULL},
	{79,119,20,12,(UBYTE *)"VAR",&hp_font,9,PLACETEXT_IN,NULL,NULL},
	{104,119,20,12,(UBYTE *)"&",&hp_font,10,PLACETEXT_IN,NULL,NULL},
	{129,119,20,12,(UBYTE *)"NXT",&hp_font,11,PLACETEXT_IN,NULL,NULL},
	{4,146,20,12,(UBYTE *)"'",&hp_font,12,PLACETEXT_IN,NULL,NULL},
	{29,146,20,12,(UBYTE *)"STO",&hp_font,13,PLACETEXT_IN,NULL,NULL},
	{54,146,20,12,(UBYTE *)"EVL",&hp_font,14,PLACETEXT_IN,NULL,NULL},
	{79,146,20,12,(UBYTE *)"<",&hp_font,15,PLACETEXT_IN,NULL,NULL},
	{104,146,20,12,(UBYTE *)"!",&hp_font,16,PLACETEXT_IN,NULL,NULL},
	{129,146,20,12,(UBYTE *)">",&hp_font,17,PLACETEXT_IN,NULL,NULL},
	{4,173,20,12,(UBYTE *)"SIN",&hp_font,18,PLACETEXT_IN,NULL,NULL},
	{29,173,20,12,(UBYTE *)"COS",&hp_font,19,PLACETEXT_IN,NULL,NULL},
	{54,173,20,12,(UBYTE *)"TAN",&hp_font,20,PLACETEXT_IN,NULL,NULL},
	{79,173,20,12,(UBYTE *)"Ü",&hp_font,21,PLACETEXT_IN,NULL,NULL},
	{104,173,20,12,(UBYTE *)"Æ",&hp_font,22,PLACETEXT_IN,NULL,NULL},
	{129,173,20,12,(UBYTE *)"Ç",&hp_font,23,PLACETEXT_IN,NULL,NULL},
	{4,200,42,12,(UBYTE *)"ENTER",&hp_font,24,PLACETEXT_IN,NULL,NULL},
	{54,200,20,12,(UBYTE *)"Å",&hp_font,25,PLACETEXT_IN,NULL,NULL},
	{79,200,20,12,(UBYTE *)"EEX",&hp_font,26,PLACETEXT_IN,NULL,NULL},
	{104,200,20,12,(UBYTE *)"DEL",&hp_font,27,PLACETEXT_IN,NULL,NULL},
	{129,200,20,12,(UBYTE *)"$",&hp_font,28,PLACETEXT_IN,NULL,NULL},
	{4,227,20,12,(UBYTE *)"%",&hp_font,29,PLACETEXT_IN,NULL,NULL},
	{34,227,25,12,(UBYTE *)"7",&hp_font,30,PLACETEXT_IN,NULL,NULL},
	{64,227,25,12,(UBYTE *)"8",&hp_font,31,PLACETEXT_IN,NULL,NULL},
	{94,227,25,12,(UBYTE *)"9",&hp_font,32,PLACETEXT_IN,NULL,NULL},
	{124,227,25,12,(UBYTE *)"/",&hp_font,33,PLACETEXT_IN,NULL,NULL},
	{4,254,20,12,(UBYTE *)"Ä",&hp_font,34,PLACETEXT_IN,NULL,NULL},
	{34,254,25,12,(UBYTE *)"4",&hp_font,35,PLACETEXT_IN,NULL,NULL},
	{64,254,25,12,(UBYTE *)"5",&hp_font,36,PLACETEXT_IN,NULL,NULL},
	{94,254,25,12,(UBYTE *)"6",&hp_font,37,PLACETEXT_IN,NULL,NULL},
	{124,254,25,12,(UBYTE *)"*",&hp_font,38,PLACETEXT_IN,NULL,NULL},
	{4,281,20,12,(UBYTE *)"Ö",&hp_font,39,PLACETEXT_IN,NULL,NULL},
	{34,281,25,12,(UBYTE *)"1",&hp_font,40,PLACETEXT_IN,NULL,NULL},
	{64,281,25,12,(UBYTE *)"2",&hp_font,41,PLACETEXT_IN,NULL,NULL},
	{94,281,25,12,(UBYTE *)"3",&hp_font,42,PLACETEXT_IN,NULL,NULL},
	{124,281,25,12,(UBYTE *)"-",&hp_font,43,PLACETEXT_IN,NULL,NULL},
	{4,308,20,12,(UBYTE *)"ON",&hp_font,44,PLACETEXT_IN,NULL,NULL},
	{34,308,25,12,(UBYTE *)"0",&hp_font,45,PLACETEXT_IN,NULL,NULL},
	{64,308,25,12,(UBYTE *)".",&hp_font,46,PLACETEXT_IN,NULL,NULL},
	{94,308,25,12,(UBYTE *)"SPC",&hp_font,47,PLACETEXT_IN,NULL,NULL},
	{124,308,25,12,(UBYTE *)"+",&hp_font,48,PLACETEXT_IN,NULL,NULL}
};


struct IntuiText GXText1[] = {
	2, 0, JAM1,24, 102, &hp_font, (UBYTE *)"a", &GXText1[1],
	2, 0, JAM1,49, 102, &hp_font, (UBYTE *)"b", &GXText1[2],
	2, 0, JAM1,74, 102, &hp_font, (UBYTE *)"c", &GXText1[3],
	2, 0, JAM1,99, 102, &hp_font, (UBYTE *)"d", &GXText1[4],
	2, 0, JAM1,124, 102, &hp_font, (UBYTE *)"e", &GXText1[5],
	2, 0, JAM1,149, 102, &hp_font, (UBYTE *)"f", &GXText1[6],
	2, 0, JAM1,24, 129, &hp_font, (UBYTE *)"g", &GXText1[7],
	2, 0, JAM1,49, 129, &hp_font, (UBYTE *)"h", &GXText1[8],
	2, 0, JAM1,74, 129, &hp_font, (UBYTE *)"i", &GXText1[9],
	2, 0, JAM1,99, 129, &hp_font, (UBYTE *)"j", &GXText1[10],
	2, 0, JAM1,124, 129, &hp_font, (UBYTE *)"k", &GXText1[11],
	2, 0, JAM1,149, 129, &hp_font, (UBYTE *)"l", &GXText1[12],
	2, 0, JAM1,24, 156, &hp_font, (UBYTE *)"m", &GXText1[13],
	2, 0, JAM1,49, 156, &hp_font, (UBYTE *)"n", &GXText1[14],
	2, 0, JAM1,74, 156, &hp_font, (UBYTE *)"o", &GXText1[15],
	2, 0, JAM1,99, 156, &hp_font, (UBYTE *)"p", &GXText1[16],
	2, 0, JAM1,124, 156, &hp_font, (UBYTE *)"q", &GXText1[17],
	2, 0, JAM1,149, 156, &hp_font, (UBYTE *)"r", &GXText1[18],
	2, 0, JAM1,24, 183, &hp_font, (UBYTE *)"s", &GXText1[19],
	2, 0, JAM1,49, 183, &hp_font, (UBYTE *)"t", &GXText1[20],
	2, 0, JAM1,74, 183, &hp_font, (UBYTE *)"u", &GXText1[21],
	2, 0, JAM1,99, 183, &hp_font, (UBYTE *)"v", &GXText1[22],
	2, 0, JAM1,124, 183, &hp_font, (UBYTE *)"w", &GXText1[23],
	2, 0, JAM1,149, 183, &hp_font, (UBYTE *)"x", &GXText1[24],
	2, 0, JAM1,74, 210, &hp_font, (UBYTE *)"y", &GXText1[25],
	2, 0, JAM1,99, 210, &hp_font, (UBYTE *)"z", &GXText1[26],
	2, 0, JAM1,2, 322, &hp_font, (UBYTE *)"cancel", NULL
	};

struct IntuiText GXText2[] = {
	1, 0, JAM1,1, 112, &hp_font, (UBYTE *)"rad", &GXText2[1],
	1, 0, JAM1,127, 112, &hp_font, (UBYTE *)"pre", &GXText2[2],
	1, 0, JAM1,1, 139, &hp_font, (UBYTE *)"up", &GXText2[3],
	1, 0, JAM1,27, 139, &hp_font, (UBYTE *)"def", &GXText2[4],
	1, 0, JAM1,52, 139, &hp_font, (UBYTE *)"num", &GXText2[5],
	1, 0, JAM1,81, 139, &hp_font, (UBYTE *)"pict", &GXText2[6],
	1, 0, JAM1,106, 139, &hp_font, (UBYTE *)"view", &GXText2[7],
	1, 0, JAM1,132, 139, &hp_font, (UBYTE *)"swap", &GXText2[8],
	1, 0, JAM1,3, 166, &hp_font, (UBYTE *)"asin", &GXText2[9],
	1, 0, JAM1,27, 166, &hp_font, (UBYTE *)"acos", &GXText2[10],
	1, 0, JAM1,52, 166, &hp_font, (UBYTE *)"atan", &GXText2[11],
	1, 0, JAM1,78, 163, &hp_font, (UBYTE *)"½", &GXText2[12],
	1, 0, JAM1,102, 164, &hp_font, (UBYTE *)"¾", &GXText2[13],
	1, 0, JAM1,130, 163, &hp_font, (UBYTE *)"·", &GXText2[14],
	1, 0, JAM1,3, 193, &hp_font, (UBYTE *)"equa", &GXText2[15],
	1, 0, JAM1,50, 193, &hp_font, (UBYTE *)"ed", &GXText2[16],
	1, 0, JAM1,74, 193, &hp_font, (UBYTE *)"purg", &GXText2[17],
	1, 0, JAM1,104, 193, &hp_font, (UBYTE *)"clear", &GXText2[18],
	1, 0, JAM1,131, 193, &hp_font, (UBYTE *)"drop", &GXText2[19],
	1, 0, JAM1,1, 220, &hp_font, (UBYTE *)"usr", &GXText2[20],
	1, 0, JAM1,127, 219, &hp_font, (UBYTE *)"()", &GXText2[21],
	1, 0, JAM1,127, 246, &hp_font, (UBYTE *)"[]", &GXText2[22],
	1, 0, JAM1,124, 273, &hp_font, (UBYTE *)"«»", &GXText2[23],
	1, 0, JAM1,1, 301, &hp_font, (UBYTE *)"cont", &GXText2[24],
	1, 0, JAM1,38, 299, &hp_font, (UBYTE *)"=", &GXText2[25],
	1, 0, JAM1,67, 297, &hp_font, (UBYTE *)",", &GXText2[26],
	1, 0, JAM1,98, 300, &hp_font, (UBYTE *)"¶", &GXText2[27],
	1, 0, JAM1,126, 299, &hp_font, (UBYTE *)"{}", &GXText2[28],
	3, 0, JAM1,15, 112, &hp_font, (UBYTE *)"pol", &GXText2[29],
	3, 0, JAM1,29, 112, &hp_font, (UBYTE *)"chars", &GXText2[30],
	3, 0, JAM1,54, 112, &hp_font, (UBYTE *)"modes", &GXText2[31],
	3, 0, JAM1,77, 112, &hp_font, (UBYTE *)"memory", &GXText2[32],
	3, 0, JAM1,104, 112, &hp_font, (UBYTE *)"stack", &GXText2[33],
	3, 0, JAM1,141, 112, &hp_font, (UBYTE *)"men", &GXText2[34],
	3, 0, JAM1,10, 139, &hp_font, (UBYTE *)"home", &GXText2[35],
	3, 0, JAM1,39, 139, &hp_font, (UBYTE *)"rcl", &GXText2[36],
	3, 0, JAM1,65, 139, &hp_font, (UBYTE *)"und", &GXText2[37],
	3, 0, JAM1,19, 164, &hp_font, (UBYTE *)"~", &GXText2[38],
	3, 0, JAM1,44, 164, &hp_font, (UBYTE *)"³", &GXText2[39],
	3, 0, JAM1,69, 164, &hp_font, (UBYTE *)"°", &GXText2[40],
	3, 0, JAM1,87, 162, &hp_font, (UBYTE *)"¼", &GXText2[41],
	3, 0, JAM1,114, 166, &hp_font, (UBYTE *)"log", &GXText2[42],
	3, 0, JAM1,140, 166, &hp_font, (UBYTE *)"ln", &GXText2[43],
	3, 0, JAM1,22, 193, &hp_font, (UBYTE *)"matrix", &GXText2[44],
	3, 0, JAM1,59, 193, &hp_font, (UBYTE *)"cmd", &GXText2[45],
	3, 0, JAM1,91, 193, &hp_font, (UBYTE *)"arg", &GXText2[46],
	3, 0, JAM1,15, 220, &hp_font, (UBYTE *)"entr", &GXText2[47],
	3, 0, JAM1,37, 220, &hp_font, (UBYTE *)"solve", &GXText2[48],
	3, 0, JAM1,68, 220, &hp_font, (UBYTE *)"plot", &GXText2[49],
	3, 0, JAM1,92, 220, &hp_font, (UBYTE *)"symbolic", &GXText2[50],
	3, 0, JAM1,139, 219, &hp_font, (UBYTE *)"#", &GXText2[51],
	3, 0, JAM1,38, 247, &hp_font, (UBYTE *)"time", &GXText2[52],
	3, 0, JAM1,69, 247, &hp_font, (UBYTE *)"stat", &GXText2[53],
	3, 0, JAM1,97, 247, &hp_font, (UBYTE *)"units", &GXText2[54],
	3, 0, JAM1,139, 246, &hp_font, (UBYTE *)"_", &GXText2[55],
	3, 0, JAM1,40, 274, &hp_font, (UBYTE *)"i\\o", &GXText2[56],
	3, 0, JAM1,64, 274, &hp_font, (UBYTE *)"library", &GXText2[57],
	3, 0, JAM1,97, 274, &hp_font, (UBYTE *)"eq lib", &GXText2[58],
	3, 0, JAM1,141, 273, &hp_font, (UBYTE *)"\" \"", &GXText2[59],
	3, 0, JAM1,19, 301, &hp_font, (UBYTE *)"off", &GXText2[60],
	3, 0, JAM1,47, 301, &hp_font, (UBYTE *)"¹", &GXText2[61],
	3, 0, JAM1,76, 301, &hp_font, (UBYTE *)"@", &GXText2[62],
	3, 0, JAM1,109, 300, &hp_font, (UBYTE *)"µ", &GXText2[63],
	3, 0, JAM1,140, 300, &hp_font, (UBYTE *)": :", NULL
};

struct IntuiText SXText[2] = {
	3, 0, JAM1,142, 193, &hp_font, (UBYTE *)"clr", &SXText[1],
	1, 0, JAM1,94, 274, &hp_font, (UBYTE *)"cmd", NULL
	};

struct TagItem ButtonTags[] = {
	{ TAG_END }
	};

int x_GX[] = {
	-2,-4,			/* SHL */
	3,2,-6,-6,3,0,
	0,2,2,4,4,0,
	-3,3,2,3,1,
	-2,0,
	0,
	4,
	0,0,2,0,2,
	-7,2,2,3,2,-4, /* SHR */
	2,1,-2,
	0,0,0,3,-1,0,
	13,9,3,
	-2,3,5,4,0,
	4,0,3,0,
	4,3,2,-6,
	-3,3,4,0,0
	};

int y_GX[] = {
	0,0,		/* SHL */
	0,0,0,0,0,0,
	0,0,0,2,1,2,
	0,0,0,0,0,
	0,1,
	0,
	1,
	0,0,2,2,1,
	0,0,0,0,0,0, /* SHR */
	0,0,0,
	3,3,3,3,0,0,
	0,0,0,
	0,0,0,0,1,
	0,0,0,0,
	0,0,0,1,
	0,-1,0,2,1
	};

void *visi;
UWORD offx,offy;
UBYTE *PubScreenName ="Workbench";
char *AppPortName = "Alcuin AppIcon";
char *Hilfe="Special Keys:\n\n\
F1 ........ ON A F ..... Reset\n\
F2 ........ ON B   ..... Oops\n\
F3 ........ ON C   ..... Warmstart\n\
F4 ........ ON D   ..... Testmode\n\
F5 ........ ON E   ..... Looping selftest\n\
F6 ........ ON 4   ..... Cancel Alarm\n\
F7 ........ ON 1   ..... Screen dump\n\
F8 ........ ON +   ..... More contrast\n\
F9 ........ ON -   ..... Less contrast\n\
F10........ ON SPC ..... Coma mode\n";
char User[40],Num[8];
int menu_reset=0;
int keybuf[10][2]={
	{0,0},
	{0,0},
	{0,0},
	{0,0},
	{0,0},
	{0,0},
	{0,0},
	{0,0},
	{0,0},
	{0,0},
};

/************************************************************/
void sage(char *str,int entry,char *substr)
{
es.es_TextFormat=(STRPTR)GetCatalogStr(mycatalog,entry,str);
EasyRequest(NULL,&es,0L,substr);
}

/************************************************************/
void CloseUp()
{
int i;

closelocale();
closetime();
closeserial();
closesound();
if (saturn_rom)		FreeMem(saturn_rom,rom_size);
if (saturn_ram)		FreeMem(saturn_ram,ram_size);
if (saturn_port1)	FreeMem(saturn_port1,port1_size);
if (saturn_port2)	FreeMem(saturn_port2,port2_size);
free_gfx();
if (menu) {
	ClearMenuStrip(win);
	FreeMenus(menu);
	}
if (myport)			DeletePort(myport);
if (dobj)			FreeDiskObject(dobj);
if (visi)			FreeVisualInfo(visi);
if (win)			CloseWindow(win);
if (scr)			UnlockPubScreen(PubScreenName,scr);
if (ConT)			FreeGadgets(ConT);
if (font)			CloseFont(font);
if (AslBase)		CloseLibrary(AslBase);
if (DiskfontBase)	CloseLibrary(DiskfontBase);
if (LocaleBase)		CloseLibrary(LocaleBase);
if (IconBase)		CloseLibrary(IconBase);
if (WorkbenchBase)	CloseLibrary(WorkbenchBase);
if (DOSBase)		CloseLibrary(DOSBase);
if (GfxBase)		CloseLibrary(GfxBase);
if (GadToolsBase)	CloseLibrary(GadToolsBase);
if (IntuitionBase)	CloseLibrary(IntuitionBase);
}

/************************************************************/
void die (char *str)
{
es.es_TextFormat=str;
EasyRequest(NULL,&es,0L,NULL);
CloseUp ();
exit (0);
}
/************************************************************/
void stirb (char *str,int entry,char *substr)
{
es.es_TextFormat=(STRPTR)GetCatalogStr(mycatalog,entry,str);
EasyRequest(NULL,&es,0L,substr);
CloseUp ();
exit (0);
}

/************************************************************/
void exit_Alcuin()
{
exit_emulator();
CloseUp();
exit (0);
}

/************************************************************/
void OpenUp()
{
if (!(LocaleBase = (struct Library *)OpenLibrary ("locale.library", 38)))
	die ("Can't open locale.library.\0");
openlocale();
es.es_Title=(STRPTR)GetCatalogStr(mycatalog,30,"Alcuin informs");
es.es_GadgetFormat=(STRPTR)GetCatalogStr(mycatalog,31,"Okay");
if (!(IntuitionBase = (struct IntuitionBase *)OpenLibrary ("intuition.library", 0)))
	stirb ("Can't open %s.",100,"intuition.library\0");
if (!(GadToolsBase = (struct GadToolsBase *)OpenLibrary ("gadtools.library", 0)))
	stirb ("Can't open %s.",100,"gadtools.library\0");
if (FastGraph)
	if (!(GfxBase = (struct GfxBase *)OpenLibrary ("graphics.library", 40)))
		stirb ("Can't open %s.",100,"graphics.library V40\0");
else
	if (!(GfxBase = (struct GfxBase *)OpenLibrary ("graphics.library", 0)))
		stirb ("Can't open %s.",100,"graphics.library\0");
if (!(DOSBase = (struct DOSBase *)OpenLibrary ("dos.library", 0)))
	stirb ("Can't open %s.",100,"dos.library\0");
if (!(AslBase = (struct Library *)OpenLibrary ("asl.library", 0)))
	stirb ("Can't open %s.",100,"asl.library\0");
if (!(DiskfontBase = (struct Library *)OpenLibrary ("diskfont.library", 0)))
	stirb ("Can't open %s.",100,"diskfont.library\0");
if (!(WorkbenchBase = (struct Library *)OpenLibrary ("workbench.library", 0)))
	stirb ("Can't open %s.",100,"workbench.library\0");
if (!(IconBase = (struct Library *)OpenLibrary ("icon.library", 0)))
	stirb ("Can't open %s.",100,"icon.library\0");
}

/************************************************************/
void OpenRest()
{
opentime();
openserial();
opensound();
if (!(scr = (struct Screen *)LockPubScreen (PubScreenName)))
	stirb ("Can't lock %s.",114,"\0");
if (!(visi = (void *)GetVisualInfoA (scr, TAG_DONE )))
	stirb ("Can't get %s.",115,"visual info\0");
if (double_res) {
	if (!(font=(struct TextFont *)OpenDiskFont(&hp_font_big)))
		stirb ("Can't open %s.",100,"hp48.font/13\0");
	}
else {
	if (!(font=(struct TextFont *)OpenDiskFont(&hp_font)))
		stirb ("Can't open %s.",100,"hp48.font/9\0");
	}
}

/************************************************************/
void OpenRestRest()
{
struct Gadget *gad;
int i,buf,Test;

if (key) {
	strcpy(regist,(STRPTR)GetCatalogStr(mycatalog,40,(STRPTR)"Registered to: "));
	strcat(regist,User);
	strcat(regist,"\n");
	strcat(regist,(STRPTR)GetCatalogStr(mycatalog,41,(STRPTR)"Serialnumber: "));
	strcat(regist,Num);
/*	strcat(regist,"\n");*/
	}
FensterTags[2].ti_Data=WinX;
FensterTags[3].ti_Data=WinY;
if (compact) {
	if (double_res) {
		FensterTags[4].ti_Data=296;
		FensterTags[5].ti_Data=623;
		}
	else {
		FensterTags[4].ti_Data=168;
		FensterTags[5].ti_Data=314;
		}
	}
else 
	if (double_res) {
		FensterTags[4].ti_Data=575;
		FensterTags[5].ti_Data=313;
		}
gad = (struct Gadget *)CreateContext((struct Gadget **)&ConT);
FensterTags[6].ti_Data=(struct Gadget *)ConT;

FensterMenu[0].nm_Label=(STRPTR)GetCatalogStr(mycatalog,0,(STRPTR)"Project");
FensterMenu[1].nm_Label=(STRPTR)GetCatalogStr(mycatalog,1,(STRPTR)"About...");
FensterMenu[3].nm_Label=(STRPTR)GetCatalogStr(mycatalog,9,(STRPTR)"Help...");
FensterMenu[5].nm_Label=(STRPTR)GetCatalogStr(mycatalog,2,(STRPTR)"Reset");
FensterMenu[7].nm_Label=(STRPTR)GetCatalogStr(mycatalog,4,(STRPTR)"Iconify");
FensterMenu[9].nm_Label=(STRPTR)GetCatalogStr(mycatalog,5,(STRPTR)"Quit");
FensterMenu[10].nm_Label=(STRPTR)GetCatalogStr(mycatalog,6,(STRPTR)"Quit & Save");

if (!(menu = (struct Menu *)CreateMenusA(FensterMenu,MenuTags)))
	stirb ("Can't create %s.",101,"Menu");
LayoutMenusA(menu,visi,NULL);
if (!(win = (struct Window *)OpenWindowTagList (NULL,FensterTags)))
    stirb ("Can't open %s.",100,(STRPTR)GetCatalogStr(mycatalog,200,"window"));
SetMenuStrip(win,menu);
rp=win->RPort;
offx = win->BorderLeft;
offy = win->BorderTop;
BoxTags[2].ti_Data = (void *)visi;
if (double_res) {
	GXText1[26].LeftEdge+=2;
	if (compact) {
		for (i=18;i<49;i++) {
			GXButton[i].ng_LeftEdge+=155;
			GXButton[i].ng_TopEdge-=162;
			}
		for (i=18;i<27;i++) {
			GXText1[i].LeftEdge+=155;
			GXText1[i].TopEdge-=162;
			}
		}
	GXButton[14].ng_GadgetText=(UBYTE *)"EVAL";
	for (i=0;i<49;i++) {
		GXButton[i].ng_VisualInfo =(void *)visi;
		GXButton[i].ng_LeftEdge *= 2;
		buf=GXButton[i].ng_TopEdge;
		GXButton[i].ng_TopEdge=(int)(1.7*(float) buf);
		GXButton[i].ng_Width *=2;
		GXButton[i].ng_Height *=2;
		GXButton[i].ng_LeftEdge +=offx+3;
		GXButton[i].ng_TopEdge +=offy+8;
		GXButton[i].ng_TextAttr=&hp_font_big;
		b[i] = gad = (struct Gadget *)CreateGadgetA(BUTTON_KIND,gad,&GXButton[i],ButtonTags);
		}
	if (!opt_gx) {
		GXText1[26].IText=(UBYTE*)"attn";
		GXText1[26].LeftEdge+=3;
		}
	for (i=0;i<27;i++) {
		GXText1[i].ITextFont=&hp_font_big;
		buf=GXText1[i].TopEdge;
		GXText1[i].TopEdge=(int)(1.7*(float) buf);;
		GXText1[i].LeftEdge*=2;
		GXText1[i].LeftEdge+=4;
		GXText1[i].TopEdge+=12;
		}
	PrintIText(rp,GXText1,offx,offy);
	DrawBevelBoxA (rp, offx + 21, offy + 5, 271, 150, BoxTags);
	}
else {
	if (compact) {
		for (i=18;i<49;i++) {
			GXButton[i].ng_LeftEdge+=160;
			GXButton[i].ng_TopEdge-=162;
			}
		for (i=18;i<27;i++) {
			GXText1[i].LeftEdge+=160;
			GXText1[i].TopEdge-=162;
			}
		}
	for (i=0;i<49;i++) {
		GXButton[i].ng_VisualInfo =(void *)visi;
		GXButton[i].ng_LeftEdge +=offx;
		GXButton[i].ng_TopEdge +=offy;
		b[i] = gad = (struct Gadget *)CreateGadgetA(BUTTON_KIND,gad,&GXButton[i],ButtonTags);
		}
	if (!opt_gx) {
		GXText1[26].IText=(UBYTE*)"attn";
		GXText1[26].LeftEdge+=5;
		}
	PrintIText(rp,GXText1,offx,offy);
	DrawBevelBoxA (rp, offx + 8, offy + 5, 138, 80, BoxTags);
	}
if (opt_gx) {
	if (double_res) {
		GXText2[1].IText=(UBYTE*)"prev";
		GXText2[4].IText=(UBYTE*)"¹num";
		GXText2[5].IText=(UBYTE*)"picture";
		GXText2[14].IText=(UBYTE*)"equation";
		GXText2[15].IText=(UBYTE*)"edit";
		GXText2[16].IText=(UBYTE*)"purge";
		GXText2[19].IText=(UBYTE*)"user";
		GXText2[28].IText=(UBYTE*)"polar";
		GXText2[33].IText=(UBYTE*)"menu";
		GXText2[34].IText=(UBYTE*)"home";
		GXText2[36].IText=(UBYTE*)"undo";
		GXText2[46].IText=(UBYTE*)"entry";
		for (i=0;i<65;i++) {
			GXText2[i].ITextFont=&hp_font_big;
			GXText2[i].LeftEdge*=2;
			buf=GXText2[i].TopEdge;
			GXText2[i].TopEdge=(int)(1.7*(float)buf);
			GXText2[i].LeftEdge+=4+x_GX[i];
			GXText2[i].TopEdge+=8+y_GX[i];
			}
		if (compact) {
			for (i=8;i<28;i++) {
				GXText2[i].LeftEdge+=310;
				GXText2[i].TopEdge-=275;
				}
			for (i=37;i<65;i++) {
				GXText2[i].LeftEdge+=310;
				GXText2[i].TopEdge-=275;
				}
			}
		PrintIText(rp,GXText2,offx,offy);
		}
	else {
		if (compact) {
			for (i=8;i<28;i++) {
				GXText2[i].LeftEdge+=160;
				GXText2[i].TopEdge-=162;
				}
			for (i=37;i<65;i++) {
				GXText2[i].LeftEdge+=160;
				GXText2[i].TopEdge-=162;
				}
			}
		PrintIText(rp,GXText2,offx,offy);
		}
	}
else {
	GXText2[0].LeftEdge+=30;
	GXText2[1].LeftEdge-=64;
	GXText2[4].LeftEdge+=2;
	GXText2[5].LeftEdge-=3;
	GXText2[6].LeftEdge-=3;
	GXText2[16].LeftEdge+=5;
	GXText2[18].LeftEdge-=5;
	GXText2[28].LeftEdge-=10;
	GXText2[29].LeftEdge+=5;
	GXText2[33].LeftEdge-=9;
	GXText2[36].LeftEdge-=3;
	GXText2[44].LeftEdge+=2;
	GXText2[45].LeftEdge-=2;
	GXText2[49].LeftEdge+=2;
	GXText2[55].LeftEdge+=3;
	GXText2[56].LeftEdge+=16;
	GXText2[57].LeftEdge+=10;
	GXText2[0].TopEdge=274;
	GXText2[1].TopEdge=274;
	GXText2[0].IText=(UBYTE*)"rad";
	GXText2[1].IText=(UBYTE*)"stack";
	GXText2[4].IText=(UBYTE*)"¹q";
	GXText2[5].IText=(UBYTE*)"graph";
	GXText2[6].IText=(UBYTE*)"review";
	GXText2[16].IText=(UBYTE*)"§d";
	GXText2[17].IText=(UBYTE*)"purge";
	GXText2[18].IText=(UBYTE*)"drop";
	GXText2[28].IText=(UBYTE*)"print";
	GXText2[29].IText=(UBYTE*)"i\\o";
	GXText2[32].IText=(UBYTE*)"library";
	GXText2[33].IText=(UBYTE*)"prev";
	GXText2[36].IText=(UBYTE*)"¹num";
	GXText2[44].IText=(UBYTE*)"visit";
	GXText2[45].IText=(UBYTE*)"©d";
	GXText2[49].IText=(UBYTE*)"algebra";
	GXText2[55].IText=(UBYTE*)"polar";
	GXText2[56].IText=(UBYTE*)"arg";
	GXText2[57].IText=(UBYTE*)"menu";
	if (double_res) {
		GXText2[14].IText=(UBYTE*)"equation";
		GXText2[15].IText=(UBYTE*)"edit";
		GXText2[19].IText=(UBYTE*)"user";
		GXText2[34].IText=(UBYTE*)"home";
		GXText2[46].IText=(UBYTE*)"entry";
		GXText2[0].LeftEdge+=2;
		GXText2[1].LeftEdge+=1;
		GXText2[5].LeftEdge+=5;
		GXText2[28].LeftEdge+=5;
		GXText2[32].LeftEdge-=2;
		GXText2[33].LeftEdge+=2;
		GXText2[44].LeftEdge-=2;
		GXText2[49].LeftEdge-=1;
		GXText2[55].LeftEdge-=1;
		GXText2[56].LeftEdge-=2;
		GXText2[57].LeftEdge-=2;
		for (i=0;i<64;i++) {
			GXText2[i].ITextFont=&hp_font_big;
			GXText2[i].LeftEdge*=2;
			buf=GXText2[i].TopEdge;
			GXText2[i].TopEdge=(int)(1.7*(float)buf);
			GXText2[i].LeftEdge+=4+x_GX[i];
			GXText2[i].TopEdge+=8+y_GX[i];
			}
		for (i=0;i<2;i++) {
			SXText[i].ITextFont=&hp_font_big;
			SXText[i].LeftEdge*=2;
			buf=SXText[i].TopEdge;
			SXText[i].TopEdge=(int)(1.7*(float)buf);
			SXText[i].LeftEdge+=4;
			SXText[i].TopEdge+=8;
			}
		if (compact) {
			for (i=8;i<28;i++) {
				GXText2[i].LeftEdge+=310;
				GXText2[i].TopEdge-=275;
				}
			for (i=37;i<64;i++) {
				GXText2[i].LeftEdge+=310;
				GXText2[i].TopEdge-=275;
				}
			for (i=0;i<2;i++) {
				SXText[i].LeftEdge+=310;
				SXText[i].TopEdge-=275;
				GXText2[i].LeftEdge+=310;
				GXText2[i].TopEdge-=275;
				}
			}
		PrintIText(rp,GXText2,offx,offy);
		PrintIText(rp,SXText,offx,offy);
		}
	else {
		GXText2[15].LeftEdge+=2;
		GXText2[22].LeftEdge+=2;
		GXText2[1].IText=(UBYTE*)"stak";
		GXText2[4].IText=(UBYTE*)"q";
		GXText2[36].IText=(UBYTE*)"num";
		if (compact) {
			for (i=8;i<28;i++) {
				GXText2[i].LeftEdge+=160;
				GXText2[i].TopEdge-=162;
				}
			for (i=37;i<64;i++) {
				GXText2[i].LeftEdge+=160;
				GXText2[i].TopEdge-=162;
				}
			for (i=0;i<2;i++) {
				SXText[i].LeftEdge+=160;
				SXText[i].TopEdge-=162;
				GXText2[i].LeftEdge+=160;
				GXText2[i].TopEdge-=162;
				}
			}
		PrintIText(rp,GXText2,offx,offy);
		PrintIText(rp,SXText,offx,offy);
		}
	}
GT_RefreshWindow(win,NULL);
RefreshWindowFrame(win);
init_display();
if ((myport=(struct MsgPort *) CreatePort(AppPortName,0))==NULL)
	stirb ("Can't create %s.",101,"MessagePort");
}

/************************************************************/
void winopen()
{
if (!(win = (struct Window *)OpenWindowTagList (NULL,FensterTags)))
    stirb ("Can't open %s.",100,(STRPTR)GetCatalogStr(mycatalog,200,"window")); 
SetMenuStrip(win,menu);
rp=win->RPort;
if (double_res)
	DrawBevelBoxA (rp, offx + 21, offy + 5, 271, 150, BoxTags);
else
	DrawBevelBoxA (rp, offx + 8, offy + 5, 138, 80, BoxTags);
PrintIText(rp,GXText1,offx,offy);
PrintIText(rp,GXText2,offx,offy);
if (!opt_gx) PrintIText(rp,SXText,offx,offy);
GT_RefreshWindow(win,NULL);
RefreshWindowFrame(win);
redraw_display();
}

/************************************************************/
void winclose()
{
if (win)			CloseWindow(win);
}

/************************************************************/
static inline void key_event(int code,int all_up)
{
int i=10,r,c,k=-1;

while (i--) if (!keybuf[i][0]) k=i;
if (k>=0) { 
	keybuf[k][0]=code;
	keybuf[k][1]=50;
	if (code == 0x8000) {
		for (i = 0; i < 9; i++) saturn_keybuf[i] |= 0x8000;
		do_kbd_int();
		}
	else {
		r = code >> 4;
		c = 1 << (code & 0xf);
		if (!(saturn_keybuf[r] & c)) {
			if (saturn_kbd_ien) do_kbd_int();
			saturn_keybuf[r] |= c;
			}
		}
	}
}

/************************************************************/
static inline void relkey(int code)
{
int i,r,c;

if (code == 0x8000) {
	for (i = 0; i < 9; i++) saturn_keybuf[i] &= ~0x8000;
	}
else {
	r = code >> 4;
	c = 1 << (code & 0xf);
	saturn_keybuf[r] &= ~c;
	}
}

/************************************************************/
static inline void raw_key(short key)
{
switch (key) {
	case (76):	/* ^ */
		key_event(0x71,0);
		break;
	case (77):	/* v */
		key_event(0x61,0);
		break;
	case (78):	/* -> */
		key_event(0x60,0);
		break;
	case (79):	/* <- */
		key_event(0x62,0);
		break;
	case (80):	/* F1 */
		key_event(0x8000,0);	/* RESET ON-A-F*/
		key_event(0x14,0);
		key_event(0x80,1);
		break;
	case (81):	/* F2 */
		key_event(0x8000,0);	/* OOPS ON-B */
		key_event(0x84,1);
		break;
	case (82):	/* F3 */
		key_event(0x8000,0);	/* WARMSTART ON-C */
		key_event(0x83,1);
		break;
	case (83):	/* F4 */
		key_event(0x8000,0);	/* TEST MODE ON-D */
		key_event(0x82,1);
		break;
	case (84):	/* F5 */
		key_event(0x8000,0);	/* LOOPING SELF TEST ON-E */
		key_event(0x81,1);
		break;
	case (85):	/* F6 */
		key_event(0x8000,0);	/* CANCEL ALRM ON-4 */
		key_event(0x23,1);
		break;
	case (86):	/* F7 */
		key_event(0x8000,0);	/* SCR DUMP ON-1 */
		key_event(0x13,1);
		break;
	case (87):	/* F8 */
		key_event(0x8000,0);	/* CONTR ON-+ */
		key_event(0x00,1);
		break;
	case (88):	/* F9 */
		key_event(0x8000,0);	/* CONTR ON-- */
		key_event(0x10,1);
		break;
	case (89):	/* F10 */
		key_event(0x8000,0);	/* COMA ON-SPC */
		key_event(0x01,1);
		break;
	case (96):	/* SHIFT */
		key_event(0x25,1);	/* SHL */
		break;
	case (99):	/* CTRL */
		key_event(0x35,1);	/* ALPHA */
		break;
	case (100):	/* ALT */
		key_event(0x15,1);	/* SHR */
		break;
	}
}

/************************************************************/
static inline void keypressed(short key)
{
int code;

if (key>0 && key <128)
	if ((code=Vanilla[key]) != 0xFF) key_event(code,1);
}

/************************************************************/
int GetEvent()
{
struct IntuiMessage *IMsg;
struct Gadget *gad;
struct AppIcon *appicon;
struct AppMessage *appmsg;
long class;
short code;
int wake=0,i=10;

while (i--)
	if (keybuf[i][1]--==1) {
		wake=1;
		relkey(keybuf[i][0]);
		keybuf[i][0]=0;
		}

if (IMsg=(struct IntuiMessage *)GT_GetIMsg(win->UserPort)) {
	class=IMsg->Class;
	GT_ReplyIMsg(IMsg);
	switch (class) {
		case IDCMP_VANILLAKEY:
			code=IMsg->Code;
			wake=1;
/*			printf("VANILLAKEY : %d\n",code);*/
			keypressed(code);
			break;
		case IDCMP_RAWKEY:
			code=IMsg->Code;
			wake=1;
/*			printf("RAWKEY : %d\n",code);*/
			raw_key(code);
			break;
		case IDCMP_MENUPICK:
			code=IMsg->Code;
/*			printf("code %d\n",code);*/
			switch (code) {
				case -1:		/* Nothing selected */
					break;
				case -2048:		/* About */
					es.es_TextFormat=Copyright;
					EasyRequest(NULL,&es,0L,versio,regist);
					break;
				case -1984:		/* Help */
					es.es_TextFormat=Hilfe;
					EasyRequest(NULL,&es,0L);
					break;
				case -1920:		/* Reset */
					wake=1;
					saturn_PC=0;
					menu_reset=1;
					break;
				case -1856:		/* Iconify */
					appicon=(struct AppIcon *) AddAppIconA(0L,0L,"Alcion",myport,NULL,dobj,NULL);
					winclose();
					WaitPort(myport);
					while(appmsg=(struct AppMessage *) GetMsg(myport))
					ReplyMsg((struct Message *)appmsg);
					RemoveAppIcon(appicon);
					winopen();
					break;
				case -1792:		/* exit */
					CloseUp();
					exit(0);
				case -1760:		/* quit */
					if (key) exit_emulator();
					CloseUp();
					exit(0);
				}
			break;
		case IDCMP_GADGETUP:
			gad=(struct Gadget *)IMsg->IAddress;
			key_event(But[gad->GadgetID],1);
			wake=1;
			break;
		case IDCMP_CLOSEWINDOW:
			exit_Alcuin();
			break;
		}
	}
return wake;
}

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