char message[] = "HP11, by David Gay(86-87). You may freely copy & distribute this program."; char message2[] = "Vous pouvez librement copier & distribuer ce programme."; #include "exec/types.h" #include "graphics/text.h" #include "intuition/intuition.h" #include "workbench/workbench.h" #include "workbench/startup.h" #include "libraries/dos.h" #include "libraries/arpbase.h" #include "proto/arp.h" #define NODOS #include "libraries/arp_pragmas.h" #include "proto/exec.h" #include "proto/graphics.h" #include "proto/intuition.h" #include "proto/icon.h" #include "proto/dos.h" #include "string.h" #include "math.h" #include "hp11/hp11.h" #include "hp11/io.h" #include "hp11/ins.h" #include "hp11/amiga/menus.h" #include "hp11/amiga/internal.h" #include "hp11/amiga/cbio.h" #define PROJECTWIDTH (75 + COMMWIDTH) /* Width of Project menu options */ #define EDITWIDTH (65 + COMMWIDTH) #define OPTIONSWIDTH 80 #define DECIMALWIDTH (CHECKWIDTH + 65 + COMMWIDTH) #define SPEEDWIDTH (CHECKWIDTH + 55) static struct TextAttr topaz9attr = { "topaz.font", 9, 0, 0 }; /* The text font desired */ static struct TextFont *topaz9; /* Texts for menu options */ static struct IntuiText hp11text[] = { { 2, 1, JAM1, 4, 1, NULL, "New", NULL }, { 2, 1, JAM1, 4, 1, NULL, "Open", NULL }, { 2, 1, JAM1, 4, 1, NULL, "Save", NULL }, { 2, 1, JAM1, 4, 1, NULL, "Save as", NULL }, { 2, 1, JAM1, 4, 1, NULL, "Print", NULL }, { 2, 1, JAM1, 4, 1, NULL, "Quit", NULL }, { 2, 1, JAM1, 4, 1, NULL, "Copy", NULL }, { 2, 1, JAM1, 4, 1, NULL, "Paste", NULL }, { 2, 1, JAM1, CHECKWIDTH, 1, NULL, "Radix", NULL }, { 2, 1, JAM1, CHECKWIDTH, 1, NULL, "Point", NULL }, { 2, 1, JAM1, CHECKWIDTH, 1, NULL, "Comma", NULL }, { 2, 1, JAM1, CHECKWIDTH, 1, NULL, "Speed", NULL }, { 2, 1, JAM1, CHECKWIDTH, 1, NULL, "Slow", NULL }, { 2, 1, JAM1, CHECKWIDTH, 1, NULL, "Fast", NULL }, { 2, 1, JAM1, CHECKWIDTH, 1, NULL, "Icons", NULL } }; /* The various menu items */ static struct MenuItem hp11item[] = { { &hp11item[1], 0, 0, PROJECTWIDTH, 10, /* New */ ITEMTEXT | ITEMENABLED | HIGHCOMP, 0, (APTR)&hp11text[0], NULL, 0, NULL }, { &hp11item[2], 0, 10, PROJECTWIDTH, 10, /* Open */ ITEMTEXT | ITEMENABLED | HIGHCOMP | COMMSEQ, 0, (APTR)&hp11text[1], NULL, 'O', NULL }, { &hp11item[3], 0, 20, PROJECTWIDTH, 10, /* Save */ ITEMTEXT | ITEMENABLED | HIGHCOMP, 0, (APTR)&hp11text[2], NULL, 0, NULL }, { &hp11item[4], 0, 30, PROJECTWIDTH, 10, /* Save as */ ITEMTEXT | ITEMENABLED | HIGHCOMP | COMMSEQ, 0, (APTR)&hp11text[3], NULL, 'S', NULL }, { &hp11item[5], 0, 40, PROJECTWIDTH, 10, /* Print */ ITEMTEXT | ITEMENABLED | HIGHCOMP, 0, (APTR)&hp11text[4], 0, NULL }, { NULL, 0, 50, PROJECTWIDTH, 10, /* Quit */ ITEMTEXT | ITEMENABLED | HIGHCOMP, 0, (APTR)&hp11text[5], NULL, 0, NULL }, { &hp11item[7], 0, 0, EDITWIDTH, 10, /* Copy */ ITEMTEXT | ITEMENABLED | HIGHCOMP | COMMSEQ, 0, (APTR)&hp11text[6], NULL, 'C', NULL }, { NULL, 0, 10, EDITWIDTH, 10, /* Paste */ ITEMTEXT | ITEMENABLED | HIGHCOMP | COMMSEQ, 0, (APTR)&hp11text[7], NULL, 'P', NULL }, { &hp11item[11], 0, 0, OPTIONSWIDTH, 10, /* Radix */ ITEMTEXT | ITEMENABLED | HIGHCOMP, 0, (APTR)&hp11text[8], NULL, 0, &hp11item[9] }, { &hp11item[10], 50, 9, DECIMALWIDTH, 10, /* Point */ ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT | CHECKED | COMMSEQ, 2, (APTR)&hp11text[9], NULL, '.', NULL }, { NULL, 50, 19, DECIMALWIDTH, 10, /* Comma */ ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT | COMMSEQ, 1, (APTR)&hp11text[10], NULL, ',', NULL }, { &hp11item[14], 0, 10, OPTIONSWIDTH, 10, /* Speed */ ITEMTEXT | ITEMENABLED | HIGHCOMP, 0, (APTR)&hp11text[11], NULL, 0, &hp11item[12] }, { &hp11item[13], 50, 9, SPEEDWIDTH, 10, /* Slow */ ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT | CHECKED, 2, (APTR)&hp11text[12], NULL, 0, NULL }, { NULL, 50, 19, SPEEDWIDTH, 10, /* Fast */ ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT, 1, (APTR)&hp11text[13], NULL, 0, NULL }, { NULL, 0, 20, SPEEDWIDTH, 10, /* Icons */ ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT | CHECKED, 0, (APTR)&hp11text[14], NULL, 0, NULL } }; /* The main menu options */ struct Menu hp11menu[] = { { &hp11menu[1], 0, 0, 80, 9, MENUENABLED, "Project", &hp11item[0] }, { &hp11menu[2], 100, 0, 50, 9, MENUENABLED, "Edit", &hp11item[6] }, { NULL, 170, 0, 80, 9, MENUENABLED, "Options", &hp11item[8] } }; /* state of Icons menu option */ static BOOL icons_on = TRUE; /* filename for save & open, window title */ static char filename[100], undo[100], winname[110]; /* Structures for file requester */ /* ----------------------------- */ static WORD shadowvert[] = { /* Points for shadow of ok/cancel box */ 2, 15, 2, 17, 82, 17, 82, 1, 80, 1 }; static struct Border cancelshadow = { 0, 0, 2, 0, JAM1, 5, shadowvert, NULL }; static WORD cancelvert[] = { /* Actual box */ -1, -1, 80, -1, 80, 15, -1, 15, -1, -1 }; /* This defines a box with shadow 80 points wide */ static struct Border cancelborder = { 0, 0, 2, 0, JAM1, 5, cancelvert, &cancelshadow }; /* The cancel gadget */ static struct IntuiText canceltext = { 2, 1, JAM1, 10, 4, &topaz9attr, "Cancel", NULL }; static struct Gadget cancelgadget = { NULL, -100, -25, 80, 15, /* it is 100 points from the right, 25 points from the bottom & measures 80x15 */ GADGHCOMP | GRELRIGHT | GRELBOTTOM, RELVERIFY | TOGGLESELECT | ENDGADGET, BOOLGADGET | REQGADGET, (APTR)&cancelborder, NULL, &canceltext }; static WORD okvert[] = { /* Box thickening */ 0, 0, 79, 0, 79, 14, 0, 14, 0, 0 }; static struct Border okborder = { 0, 0, 2, 0, JAM1, 5, okvert, &cancelborder }; /* Ok gadget */ static struct IntuiText oktext = { 2, 1, JAM1, 30, 4, &topaz9attr, "Ok", NULL }; static struct Gadget okgadget = { &cancelgadget, 20, -25, 80, 15, GADGHCOMP | GRELBOTTOM, RELVERIFY | TOGGLESELECT | ENDGADGET, BOOLGADGET | REQGADGET, (APTR)&okborder, NULL, &oktext }; static WORD bluevert[] = { 0, 8, 199, 8 }; static struct Border blueline = { 0, 0, 0, 0, JAM1, 2, bluevert, NULL }; static WORD namevert[] = { /* for filename box */ -1, -1, 200, -1, 200, 9, -1, 9, -1, -1 }; static struct Border nameborder = { 0, 0, 2, 0, JAM1, 5, namevert, &blueline }; static struct StringInfo nameinfo = { filename, undo, 0, 100, 0 }; static struct IntuiText nametext = { 2, 1, JAM1, -55, 0, &topaz9attr, NULL, NULL }; /* filename gadget */ static struct Gadget namegadget = { &okgadget, 62, 10, 200, 9, GADGHCOMP, ENDGADGET, STRGADGET | REQGADGET, (APTR)&nameborder, NULL, &nametext, 0, (APTR)&nameinfo }; static WORD filevert[] = { /* for the complete requester */ 0, 0, 269, 0, 269, 59, 0, 59, 0, 0 }; static struct Border fileborder = { 0, 0, 2, 0, JAM1, 5, filevert, NULL }; /* The actual requester */ static struct Requester filereq = { NULL, 25, 65, 270, 60, 0, 0, &namegadget, &fileborder, NULL, 0, 1 }; /* Message requester */ /* ----------------- */ static struct IntuiText msgtext = { 2, 1, JAM1, 10, 10, &topaz9attr, NULL, NULL }; static struct Gadget msgokgadget = { NULL, 20, -25, 80, 15, /* Message inits LeftEdge */ GADGHCOMP | GRELBOTTOM, RELVERIFY | TOGGLESELECT | ENDGADGET, BOOLGADGET | REQGADGET, (APTR)&okborder, NULL, &oktext }; static WORD msgvert[][2] = { 0, 0, 0, 0, 0, 59, 0, 59, 0, 0 }; static struct Border msgborder = { 0, 0, 2, 0, JAM1, 5, msgvert, NULL }; static struct Requester msgreq = { NULL, 0, 65, /* LeftEdge is initialised by Message */ 0, 60, /* Width also */ 0, 0, &msgokgadget, &msgborder, &msgtext, 0, 1 }; /* struct DiskObject { int a; }; Little problem: DiskObject def lost !!! */ struct Library *IconBase; /* for the icon library */ struct ArpBase *ArpBase; /* Arp lib */ extern char tool[]; /* Path to hp11 program */ extern struct DiskObject prog_icon; static BOOL clip; void LoadProg(void), OpenProg(void), StoreProg(void), SaveProg(void), Copy(void), Paste(void); BOOL MenusInit(argc, argv) int argc; APTR argv; #define argw ((struct WBStartup *)argv) #define arg1 (argw->sm_ArgList[1]) { char path[PATHLEN]; topaz9 = OpenFont(&topaz9attr); /* Open the desired font */ IconBase = OpenLibrary("icon.library", 0); if (!IconBase) { /* no icon library, disable icons */ icons_on = FALSE; hp11item[14].Flags &= ~(CHECKED | ITEMENABLED); } ArpBase = OpenLibrary("arp.library", 0); /* Set up tool path */ strcat(strcpy(tool, hp11path), hp11name); if (!(clip = !CBOpen(0))) /* Disable clip options if no clipboard */ hp11menu[1].Flags = NULL; SetMenuStrip(hp11, hp11menu); if (argc != 0) { /* CLI */ icons_on = FALSE; hp11item[14].Flags &= ~CHECKED; /* by default, no icons from cli */ if (argc > 1) { /* argument */ strcpy(filename, ((char **)argv)[1]); LoadProg(); } } else if (argw->sm_NumArgs > 1) { /* workbench, with argument */ if (!mygetpath(path, arg1.wa_Lock)) path[0] = '\0'; strcpy(filename, strcat(path, arg1.wa_Name)); LoadProg(); } return(TRUE); } #undef arg1 #undef argw void MenusCleanUp() { if (hp11) ClearMenuStrip(hp11); if (clip) CBClose(); if (ArpBase) CloseLibrary(ArpBase); if (IconBase) CloseLibrary(IconBase); if (topaz9) CloseFont(topaz9); } /* Enable menus */ void MenusOn(void) { SetMenuStrip(hp11, hp11menu); } /* Disable menus */ void MenusOff(void) { ClearMenuStrip(hp11); } void EditOn(void) { if (clip) OnMenu(hp11, SHIFTMENU(1) | SHIFTITEM(NOITEM)); } void EditOff(void) { OffMenu(hp11, SHIFTMENU(1) | SHIFTITEM(NOITEM)); } /* The menu handler, number represents the chosen option */ int MenuHandler(UWORD number) { register struct MenuItem *item; register int key = -1; MenusOff(); /* Disable menus */ while (number != MENUNULL) { switch (MENUNUM(number)) { case 0: /* Project */ switch (ITEMNUM(number)) { case 0: /* New */ HP11ColdReset(); key = BRESET; break; /* back to main loop */ case 1: /* Open */ OpenProg(); key = BRESET; break; case 2: /* Save */ StoreProg(); break; case 3: /* Save as */ SaveProg(); break; case 4: /* Print */ break; case 5: /* Quit */ quit = TRUE; key = BRESET; break; } break; case 1: /* Edit */ switch (ITEMNUM(number)) { case 0: /* Copy */ Copy(); break; case 1: /* Paste */ Paste(); key = BDISPLAY; break; } break; case 2: /* Options */ switch (ITEMNUM(number)) { case 0: /* Radix */ comma = SUBNUM(number); /* false for Point, true for Comma */ key = BDISPLAY; /* Redisplay */ break; case 1: /* Speed */ fast = SUBNUM(number); /* false for Slow, true for Fast */ break; case 2: /* Icons */ icons_on = !icons_on; /* Toggle flag */ if (icons_on) hp11item[14].Flags |= CHECKED; else hp11item[14].Flags &= ~CHECKED; break; } break; } item = ItemAddress(hp11menu, (long)number); number = item->NextSelect; } MenusOn(); return(key); } /* Display an error message */ void Message(text) char *text; { register int width; msgtext.IText = text; width = IntuiTextLength(&msgtext) + 20; /* width of requester */ if (width < 100) width = 100; /* min width */ msgokgadget.Flags &= ~SELECTED; msgreq.Width = width; msgreq.LeftEdge = (HP11WIDTH - width) >> 1; /* center rqeuester */ msgokgadget.LeftEdge = (width >> 1) - 40; /* center OK */ msgvert[1][0] = width - 1; msgvert[2][0] = width - 1; Request(&msgreq, hp11); } /* Read a file name, text is displayed to the left of the name box. Return FALSE if cancel selected, TRUE otherwise */ static BOOL GetFile(char *text) { ULONG saveIDCMP; struct IntuiMessage *msg; int done; if (ArpBase) /* Use arp file req */ { static char directory[DSIZE + 1]; static struct FileRequester FR; filename[0] = '\0'; FR.fr_Hail = text; FR.fr_File = filename; FR.fr_Dir = directory; if (FileRequest(&FR)) { long lock = Lock(directory, SHARED_LOCK); if (lock) { CurrentDir(lock); return TRUE; } } return FALSE; } else { nametext.IText = text; okgadget.Flags &= ~SELECTED; cancelgadget.Flags &= ~SELECTED; saveIDCMP = hp11->IDCMPFlags; ModifyIDCMP(hp11, REQCLEAR | REQSET); Request(&filereq, hp11); do { WaitPort(hp11->UserPort); /* Wait for requester to appear */ msg = GetMsg(hp11->UserPort); done = msg->Class == REQSET; ReplyMsg(msg); } while (!done); ActivateGadget(&namegadget, hp11, &filereq); do { WaitPort(hp11->UserPort); /* Wait for requester to disappear */ msg = GetMsg(hp11->UserPort); done = msg->Class == REQCLEAR; ReplyMsg(msg); } while (!done); ModifyIDCMP(hp11, saveIDCMP); if (!(cancelgadget.Flags & SELECTED)) { CurrentDir(DupLock(CurrentDir(0))); return TRUE; } else return FALSE; } } static void SetTitle(void) { SetWindowTitles(hp11, strcat(strcpy(winname, "HP11C - "), filename), (char *)(long)-1); } static int FileType(struct DiskObject *icon, char *type) { char *value; if (!(value = FindToolType(icon->do_ToolTypes, "FILETYPE"))) return(FALSE); return((int)MatchToolValue(value, type)); } static void LoadProg() { LONG file; struct Regs newhp11; struct DiskObject *icon = NULL; BYTE dummy; if (IconBase && (icon = GetDiskObject(filename)) && !FileType(icon, "HP11")) { Message("This isn't an HP11 program"); goto exit; } if (file = Open(filename, MODE_OLDFILE)) { if ((Read(file, (char *)&newhp11, sizeof(struct Regs)) == sizeof(struct Regs)) && (Read(file, &dummy, 1) != 1)) { /* dummy read to check file size */ hp11r = newhp11; /* Set new internal state */ running = FALSE; /* Interrupt program */ PC = 0; retCnt = 0; ENABLE(); SetTitle(); } else Message("This isn't an HP11 program"); Close(file); } else Message("Couldn't open file"); exit: if (icon) FreeDiskObject(icon); } /* Save current state under current filename */ static void StoreProg() { LONG file; struct DiskObject *temp_icon; file = Open(filename, MODE_NEWFILE); if (!file) Message("Couldn't open file"); else { if (Write(file, (char *)&hp11r, sizeof(struct Regs)) != sizeof(struct Regs)) Message("Error writing the file"); else { SetTitle(); if (icons_on) if (!(temp_icon = GetDiskObject(filename))) PutDiskObject(filename, &prog_icon); else FreeDiskObject(temp_icon); } Close(file); } } /* Save current state under a filename */ static void SaveProg() { BPTR cdir, new; CurrentDir(cdir = CurrentDir(0)); if (GetFile("Save:")) { StoreProg(); if (new = CurrentDir(cdir)) UnLock(new); } } /* Load the hp11 state */ static void OpenProg() { BPTR cdir, new; CurrentDir(cdir = CurrentDir(0)); if (GetFile("Open:")) /* Get file name */ { LoadProg(); if (new = CurrentDir(cdir)) UnLock(new); } } static void Copy() { CBCut(NbStr(X)); } static void Paste() { char buf[256]; if (CBPaste(buf)) { Enter(); ENABLE(); X = Check(atof(buf)); } }