[comp.sources.amiga] v89i198: hp11 calculator emulator v1.01, Part01/03

page%swap@Sun.COM (Bob Page) (11/13/89)

Submitted-by: dg3i+@andrew.cmu.edu (David Gay)
Posting-number: Volume 89, Issue 198
Archive-name: applications/hp11.1

A new version of this RPN calculator emulator.

# This is a shell archive.
# Remove anything above and including the cut line.
# Then run the rest of the file through 'sh'.
# Unpacked files will be owned by you and have default permissions.
#----cut here-----cut here-----cut here-----cut here----#
#!/bin/sh
# shar: SHell ARchive
# Run the following text through 'sh' to create:
#	amiga/amiga.c
#	amiga/amiga.h
#	amiga/cbio.c
#	amiga/cbio.h
#	amiga/chars.c
#	amiga/chip.c
# This is archive 1 of a 3-part kit.
# This archive created: Sun Nov 12 17:33:20 1989
if `test ! -d amiga`
then
  mkdir amiga
  echo "mkdir amiga"
fi
echo "extracting amiga/amiga.c"
sed 's/^X//' << \SHAR_EOF > amiga/amiga.c
X#include "exec/types.h"
X#include "exec/ports.h"
X#include "exec/io.h"
X#include "exec/memory.h"
X#include "graphics/gfx.h"
X#include "devices/timer.h"
X#include "libraries/dos.h"
X#include "workbench/startup.h"
X
X#include "proto/exec.h"
X#include "proto/graphics.h"
X#include "proto/layers.h"
X#include "proto/intuition.h"
X#include "proto/timer.h"
X#include "proto/dos.h"
X
X#include "string.h"
X#include "ctype.h"
X#include "dos.h"
X
X#include "hp11/hp11.h"
X#include "hp11/amiga/internal.h"
X#include "hp11/amiga/amiga.h"
X#include "hp11/amiga/menus.h"
X
X#define MAXWIDTH 29 /* X distance between 2 keys */
X#define MAXHEIGHT 29 /* Y distance bewteen 2 keys */
X#define KEYWIDTH 20 /* Width of actual key */
X#define KEYHEIGHT 16 /* Height of actual key */
X#define TOPKEYHEIGHT 9 /* Height of top of key */
X#define KEYX (19 + HP11X) /* Position of first key */
X#define KEYY (61 + HP11Y)
X#define CHAROFFX -1 /* offset in display for first char */
X#define CHAROFFY 3
X#define CHARWIDTH 14 /* Size of char */
X#define CHARHEIGHT 13
X#define SCRX0 (53 + HP11X) /* Limits of display for chars */
X#define SCRX1 (208 + HP11X)
X#define SCRY0 (11 + HP11Y)
X#define SCRY1 (37 + HP11Y)
X#define fX (SCRX0 + 3 * CHARWIDTH + 2) /* Position of indicators */
X#define gX (SCRX0 + 4 * CHARWIDTH - 1)
X#define GX (SCRX0 + (int)(6.5 * CHARWIDTH))
X#define RADX (GX + 5)
X#define PRGMX (SCRX0 + 10 * CHARWIDTH - 6)
X#define USERX (SCRX0 + CHARWIDTH)
X#define INDICY (SCRY0 + 19)
X
X#define CR 13
X#define BS 8
X#define ESC 27
X
X#define COPY 0xc0 /* minterm for straight copy */
X
Xstruct Library *TimerBase; /* Base for calling timer routines */
X
Xextern struct Border *hp11char[]; /* Character descriptions (as connected lines) */
X/* Indicator shapes (as bitmaps) */
Xextern struct Image fImage, gImage, USERImage, GImage, RADImage, PRGMImage;
Xextern struct Image off_image; /* Image for sleep */
X
Xextern struct IntuitionBase *IntuitionBase;
Xextern struct GfxBase *GfxBase;
Xstruct LayersBase *LayersBase;
X
Xstruct Window *hp11; /* The window containing the hp11 */
X
X/* These informations are for RelKey() */
X/* The method by which the latest key was obtained :
X  From the menus, from the CLOSE gadget, from the keyboard, or by selecting with the mouse */
Xstatic enum {menu, gadget, keyboard, mouse} keytype;
X/* The keycode of the last key read */
Xstatic short lastkey;
X/* The Time at which the last key was read */
Xstatic ULONG secs, micros;
X/* Path to executable */
Xchar *hp11name;
Xchar hp11path[PATHLEN];
X
Xstatic struct timerequest *timer; /* The timer which is used */
Xstatic struct NewWindow hp11new = { /* Desired window */
X   0,0, /* Position of top left corner */
X   HP11WIDTH + 6, HP11HEIGHT + 14, /* Width, Height */
X   -1,-1, /* Use default pens to draw window */
X   CLOSEWINDOW | MOUSEBUTTONS | VANILLAKEY | MENUPICK,
X   WINDOWDEPTH | WINDOWCLOSE | WINDOWDRAG | SMART_REFRESH | NOCAREREFRESH,
X   NULL, NULL,
X   "HP11C", NULL,
X   NULL,
X   0, 0, 0, 0,
X   WBENCHSCREEN /* It opens in the main screen */
X};
X
Xstatic struct IntuiText canceltext = {
X   AUTOFRONTPEN, AUTOBACKPEN,
X   AUTODRAWMODE,
X   AUTOLEFTEDGE, AUTOTOPEDGE,
X   AUTOITEXTFONT,
X   "Cancel",
X   AUTONEXTTEXT
X};
X
Xstatic struct IntuiText nomemtext = {
X   AUTOFRONTPEN, AUTOBACKPEN,
X   AUTODRAWMODE,
X   20, 10,
X   AUTOITEXTFONT,
X   "Not enough memory",
X   NULL
X};
X
Xchar *mygetpath(to, l)
Xregister char *to;
Xregister BPTR l;
X{
X   register BPTR tl;
X   register int notfirst = FALSE;
X   register struct FileInfoBlock *fib = (struct FileInfoBlock *)AllocMem(sizeof(struct FileInfoBlock), 0);
X
X   if (!fib) return(NULL);
X   to[0] = '\0';
X
X   do {
X      if (!Examine(l, fib)) return(NULL);
X      if (fib->fib_DirEntryType > 0) strins(to, "/");
X      if (fib->fib_FileName[0] == '\0') strins(to, "RAM");
X      else strins(to, fib->fib_FileName);
X      tl = l;
X      l = ParentDir(l);
X      if (notfirst) UnLock(tl);
X      notfirst = TRUE;
X   } while (l);
X
X   *(strchr(to, '/')) = ':';
X   FreeMem((char *)fib, sizeof(struct FileInfoBlock));
X   return(to);
X}
X
Xvoid split(char *file, char *path, char **name)
X{
X   int l = strlen(file);
X
X   *name = file + l;
X   while (--l >= 0 && (*--*name != '/' && **name != ':')) ;
X   if (l < 0)
X      path[0] = '\0';
X   else
X   {
X      ++*name;
X      strncpy(path, file, l + 1);
X      path[l + 1] = '\0';
X   }
X}
X
X/* Delete a timer */
Xstatic void DeleteTimer(struct timerequest *tr)
X{
X   TimerBase = (struct Library *)(-1); /* Don't call any more ! */
X
X   if (tr != NULL)
X   {
X      /* Remove the port */
X      if (tr->tr_node.io_Message.mn_ReplyPort) DeletePort(tr->tr_node.io_Message.mn_ReplyPort);
X
X      CloseDevice((struct IORequest *)tr); /* Close the device */
X      DeleteExtIO((struct IORequest *)tr); /* Free the IO request */
X   }
X}
X
X/* Create a timer of type unit */
Xstatic struct timerequest *CreateTimer(ULONG unit)
X{
X   register long error;
X
X   register struct MsgPort *timerport;
X   register struct timerequest *timermsg;
X
X   if ((timerport = CreatePort(NULL, 0)) == NULL) /* first get a port */
X      return(NULL); /* failed */
X
X   if ((timermsg = (struct timerequest *) /* Then create an IO request for the timer */
X		   CreateExtIO(timerport, sizeof(struct timerequest))) == NULL)
X      return(NULL); /* failed */
X
X   if ((error = OpenDevice(TIMERNAME, unit, (struct IORequest *)timermsg, 0)) != 0) /* Finally, open the timer device */
X   { /* failed */
X      DeleteTimer(timermsg);
X      return(NULL);
X   }
X
X   TimerBase = (struct Library *)timermsg->tr_node.io_Device; /* Allow calls to the time arithmetic routines */
X   return(timermsg);
X}
X
X/* Wait for a specified duration */
Xstatic void WaitFor(struct timeval *tv)
X{
X   timer->tr_node.io_Command = TR_ADDREQUEST;
X
X   timer->tr_time = *tv;
X
X   DoIO((struct IORequest *)timer); /* Wait for completion of request */
X}
X
X/* Obtain the system time, assume global timer contains a valid timer */
Xstatic void GetSysTime(struct timeval *tv)
X{
X   timer->tr_node.io_Command = TR_GETSYSTIME;
X   DoIO((struct IORequest *)timer);
X
X   *tv = timer->tr_time; /* Copy obtained time */
X}
X
X/* Reverse the key on the keyboard (as if user was holding it down) */
Xstatic void ReverseKey(int key)
X{
X   register int kx, ky, h;
X
X   if (key == 30) h = KEYHEIGHT - 1; /* ON, higher than average */
X   else if (key == 25) h = MAXHEIGHT + TOPKEYHEIGHT - 1; /* ENTER, even taller */
X   else h = TOPKEYHEIGHT - 1;
X
X/* -------------------- */
X/* Check for bug when using short int */
X
X   kx = (key % 10) * MAXWIDTH + KEYX; /* Calc. key position */
X   ky = (key / 10) * MAXHEIGHT + KEYY;
X
X   SetDrMd(hp11->RPort, COMPLEMENT); /* Draw in reverse */
X   RectFill(hp11->RPort, (long)kx, (long)ky, (long)(kx + (KEYWIDTH - 1)), (long)(ky + h));
X}
X
X/* From positions x & y, deduce which key was pressed */
Xstatic int DecodeKey(int x, int y)
X{
X   register int kx, ky, px, py;
X
X   kx = (x - KEYX) / MAXWIDTH; px = (x - KEYX) % MAXWIDTH;
X   ky = (y - KEYY) / MAXHEIGHT; py = (y - KEYY) % MAXHEIGHT;
X
X   if (/* first, check if in keyboard. x & y are tested (instead of kx, ky)
X	  because kx & ky suffer a roundoff towards zero for negative values */
X       (x >= KEYX && y >= KEYY && kx <= 9 && ky <= 3)
X       &&
X	  /* now the condition on width */
X       (px < KEYWIDTH && px >= 0) /* same for all keys */
X       &&
X	 /* condition on height, 2 cases for ENTER is different */
X       (
X	   (kx == 5 && (ky == 2 || (ky == 3 && py < KEYHEIGHT) && (ky = 2))) /* ENTER, set ky to correct value when ky == 3 */
X	   || /* condition on height */
X	   (py < KEYHEIGHT && py >= 0)
X       )
X      ) return(ky * 10 + kx);
X   else return(-1);
X}
X
X/* Mouse was pressed at x,y. Is this a key ? */
Xstatic int GetMouseKey(int x, int y)
X{
X   int key;
X
X   if ((key = DecodeKey(x, y)) != -1) { /* yes */
X      ReverseKey(key);
X      keytype = mouse; /* info for RelKey() */
X   }
X   return(key);
X}
X
X/* Key keycode was pressed by the user */
Xstatic int GetKeyKey(int _keycode)
X{
X   register int key = -1, keycode = tolower(_keycode);
X
X   switch (keycode) {
X      case ESC: key = 30; break;
X      case '7': case '8': case '9': key = keycode - ('7' - 6); break;
X      case '4': case '5': case '6': key = keycode - ('4' - 16); break;
X      case '1': case '2': case '3': key = keycode - ('1' - 26); break;
X      case '0': key = 36; break;
X      case '.': key = 37; break;
X      case '^': key =  3; break;
X      case '*': key = 19; break;
X      case '-': key = 29; break;
X      case '+': key = 39; break;
X      case '/': key =  9; break;
X      case '_': key =  5; break;
X      case CR : key = 25; break;
X      case 'f': key = 31; break;
X      case 'g': key = 32; break;
X      case BS : key = 24; break;
X      case 's': key = 12; break;
X      case 'c': key = 13; break;
X      case 't': key = 14; break;
X   }
X   if (key != -1) { /* A valid key was given */
X      ReverseKey(key);
X      keytype = keyboard; /* for RelKey() */
X   }
X   return(key);
X}
X
X/* Get a key from the keyboard with/without waiting */
Xint PollKey(wait)
Xint wait;
X{
X   register int key;
X   register struct IntuiMessage *msg;
X   register ULONG class;
X   register UWORD code;
X   register WORD x, y;
X   register APTR address;
X
X   key = -1; /* no key yet */
X   do {
X      if (wait) WaitPort(hp11->UserPort); /* No active waits in multi-tasking ! */
X      msg = (struct IntuiMessage *)GetMsg(hp11->UserPort); /* Get the message if there is one */
X      if (msg) { /* yes, there is */
X	 /* Copy relevant information */
X	 class = msg->Class;
X	 code = msg->Code;
X	 address = msg->IAddress;
X	 x = msg->MouseX;
X	 y = msg->MouseY;
X	 secs = msg->Seconds;
X	 micros = msg->Micros;
X	 ReplyMsg((struct Message *)msg); /* & reply to it */
X
X	 switch (class) { /* type of message */
X	    case CLOSEWINDOW: /* Window closed = Quit */
X	       quit = TRUE;
X	       key = BRESET;
X	       keytype = gadget;
X	       break;
X	    case MOUSEBUTTONS: /* A mouse button was pressed */
X	       if (code == SELECTDOWN)
X		  key = GetMouseKey(x, y);
X	       break;
X	    case VANILLAKEY: /* a key was pressed */
X	       key = GetKeyKey(code);
X	       break;
X	    case MENUPICK: /* A menu option was chosen */
X	       key = MenuHandler(code); /* Call menu handler */
X	       keytype = menu; /* for RelKey() */
X	       break;
X	 }
X      }
X   } while (key == -1 && (msg || wait));
X   /* Exit if key read or, if not waiting, no message ready */
X
X   lastkey = key; /* save key for RelKey() */
X   return(key);
X}
X
X/* Wait for latest key to be released, returns true if button released
X  over key (valid only for mouse) */
XBOOL RelKey()
X{
X   register WORD x, y;
X   register BOOL Released;
X   register struct IntuiMessage *msg;
X   struct timeval event, now, delay;
X   register int key = lastkey; /* key last pressed */
X
X   lastkey = -1; /* Only release it once ! */
X
X   if (key != -1)
X      switch (keytype) {
X
X	 case keyboard: /* Key reversed for a max of .08 secs
X	    (There is no easy way to wait for its release on the keyboard) */
X	    event.tv_secs = secs; event.tv_micro = micros;
X	    GetSysTime(&now);
X	    SubTime(&now, &event); /* Time elapsed since key pressed */
X	    delay.tv_secs = 0; delay.tv_micro = 80000;
X	    if (CmpTime(&now, &delay) == 1) { /* now < delay */
X	       SubTime(&delay, &now);
X	       WaitFor(&delay); /* Wait long enough */
X	    }
X	    ReverseKey(key); /* un-reverse key */
X	    return(TRUE);
X
X	 case mouse:
X	    Released = FALSE;
X	    do { /* Wait for mouse button to be released */
X	       WaitPort(hp11->UserPort);
X	       msg = (struct IntuiMessage *)GetMsg(hp11->UserPort);
X	       x = msg->MouseX;
X	       y = msg->MouseY;
X	       Released = (msg->Class == MOUSEBUTTONS && msg->Code == SELECTUP);
X	       ReplyMsg((struct Message *)msg);
X	    } while (!Released);
X	    ReverseKey(key); /* un-reverse key */
X
X	    return((BOOL)(DecodeKey(x, y) == key)); /* Button released over key? */
X      }
X   return(TRUE); /* if already released */
X}
X
X/* load picture from open file file, width pixel wide, height pixels high,
X  depth bitplanes deep into bitmap bm & colormap cols (if non-null) */
Xstatic BOOL LoadBitMap(LONG file, struct BitMap *bm, int width, int height,
X		       int depth)
X{
X   register int i;
X   register LONG nb, plsize;
X
X   InitBitMap(bm, (long)depth, (long)width, (long)height);
X   plsize = bm->BytesPerRow * bm->Rows; /* size of 1 plane */
X   /* Allocate enough memory for all planes, initialise plane pointers */
X   if (!(bm->Planes[0] = (PLANEPTR)AllocMem(plsize * depth, MEMF_CHIP))) return((BOOL) FALSE);
X   for (i = 1; i < depth; i++) bm->Planes[i] = bm->Planes[0] + plsize * i;
X
X   /* Read data from disk */
X   for (i = 0; i < bm->Depth; i++) {
X      nb = Read(file, bm->Planes[i], plsize);
X      if (nb < plsize) return((BOOL) FALSE);
X   }
X
X   return((BOOL) TRUE);
X}
X
Xvoid alert(struct Window *win, char *msg1, char *msg2)
X{
X    static struct TextAttr alert_attr = { "topaz.font", 8 };
X    struct TextFont *alert_font;
X    struct IntuiText text1, text2, negative;
X    const static struct IntuiText template = {
X	0, 1, JAM1,
X	8, 0,
X	&alert_attr
X    };
X    int width, height;
X    int ysize;
X
X    alert_font = OpenFont(&alert_attr);
X
X    ysize = alert_font ? alert_font->tf_YSize : 8;
X
X    text1 = text2 = negative = template;
X    text1.TopEdge = 8;
X    text1.IText = msg1;
X    width = IntuiTextLength(&text1) + 40;
X    height = 37 + 2 * ysize;
X    if (msg2 != NULL)
X    {
X	int w;
X
X	text1.NextText = &text2;
X	text2.TopEdge = text1.TopEdge + ysize;
X	text2.IText = msg2;
X
X	height += ysize;
X	w = IntuiTextLength(&text2) + 20;
X	if (w > width) width = w;
X    }
X    negative.LeftEdge = 6;
X    negative.TopEdge = 4;
X    negative.IText = "Ok";
X
X    AutoRequest(win, &text1, NULL, &negative, 0L, 0L, width, height);
X}
X
X/* Amiga specific initialisation */
X#define argw ((struct WBStartup *)argv)
XBOOL AmigaInit(argc, argv)
Xint argc;
XAPTR argv;
X{
X   register LONG file;
X   register BOOL loaded;
X   struct BitMap hp11bitmap;
X   BPTR hp11dir, old;
X   char filename[PATHLEN + 8];
X
X   if (!(GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 33))) /* Open graphics library (1.2) */
X      return(FALSE);
X
X   if (!(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 33))) /* Open intuition library (1.2) */
X      return(FALSE);
X
X   if (!(LayersBase = (struct LayersBase *)OpenLibrary("layers.library", 0)))
X      return(FALSE);
X
X   /* Find path to command (if possible) */
X   if (argc == 0) /* WB */
X   {
X      old = CurrentDir(argw->sm_ArgList[0].wa_Lock);
X      split(argw->sm_ArgList[0].wa_Name, hp11path, &hp11name);
X      hp11dir = Lock(hp11path, ACCESS_READ);
X      if (!mygetpath(hp11path, hp11dir)) hp11path[0] = '\0';
X      CurrentDir(old);
X      UnLock(hp11dir);
X   }
X   else
X   { /* CLI */
X      split(((char **)argv)[0], hp11path, &hp11name);
X   }
X
X   /* Read the picture */
X   if (!(file = Open(strcat(strcpy(filename, hp11path), "hp11.pic"), MODE_OLDFILE)))
X      if (!(file = Open("hp11.pic", MODE_OLDFILE)))
X      {
X	 alert(NULL, "Can't find hp11.pic", NULL);
X	 return(FALSE);
X      }
X   loaded = LoadBitMap(file, &hp11bitmap, HP11WIDTH, HP11HEIGHT, 2);
X   Close(file);
X   if (!loaded) return(FALSE);
X
X   /* Open the window */
X   if (!(hp11 = OpenWindow(&hp11new))) return(FALSE);
X
X   /* Move picture into window */
X   BltBitMapRastPort(&hp11bitmap, 0, 0, hp11->RPort, HP11X, HP11Y, HP11WIDTH, HP11HEIGHT, COPY);
X   FreeMem(hp11bitmap.Planes[0], (long)(hp11bitmap.BytesPerRow * hp11bitmap.Rows * hp11bitmap.Depth));
X
X   /* Create timer */
X   if ((timer = CreateTimer(UNIT_MICROHZ)) == NULL) return(FALSE);
X
X   /* Init menus */
X   return(MenusInit(argc, argv));
X}
X#undef argw
X
Xvoid AmigaCleanUp()
X{
X   MenusCleanUp();
X   if (timer) DeleteTimer(timer); /* Close timer */
X   if (hp11) CloseWindow(hp11);
X   if (LayersBase) CloseLibrary((struct Library *)LayersBase);
X   if (IntuitionBase) CloseLibrary((struct Library *)IntuitionBase); /* Close libraries */
X   if (GfxBase) CloseLibrary((struct Library *)GfxBase);
X}
X
X/* Display s */
Xvoid Display(s)
Xregister char *s;
X{
X   register int posx;
X   register int chr;
X   register struct RastPort *rport = hp11->RPort;
X
X   /* Clear display */
X   SetDrMd(rport, JAM1); SetAPen(rport, 2);
X   RectFill(rport, SCRX0 + 1, SCRY0, SCRX1 - 1, SCRY1);
X
X   /* Initial position */
X   posx = SCRX0 + CHAROFFX;
X
X   while (*s) {
X      switch (*s) { /* Position of char in char array */
X	 case '0': case '1': case '2': case '3': case '4': case '5': case '6':
X	 case '7': case '8': case '9': chr = *s - '0'; break;
X	 case '-': chr = 10; break;
X	 case 'E': chr = 11; break;
X	 case 'r': chr = 12; break;
X	 case 'o': chr = 13; break;
X	 case 'R': chr = 14; break;
X	 case 'u': chr = 15; break;
X	 case 'n': chr = 16; break;
X	 case 'i': chr = 17; break;
X	 case 'g': chr = 18; break;
X	 case '.': chr = 19; break;
X	 case ',': chr = 20; break;
X	 case 'P': chr = 21; break;
X	 default:  chr = -1; break;
X      }
X      if (chr != -1)
X	 DrawBorder(rport, hp11char[chr], (long)posx, SCRY0 + CHAROFFY);
X
X      if (*s != '.' && *s != ',') posx += CHARWIDTH;
X
X      s++;
X   }
X}
X
X/* Set image to be drawn/erased according to on */
Xstatic void SetCol(struct Image *im, int on)
X{
X   if (on) {
X      im->PlanePick = 3;
X      im->PlaneOnOff = 0;
X   }
X   else {
X      im->PlanePick = 0;
X      im->PlaneOnOff = 2;
X   }
X}
X
X/* Display the indicators */
Xvoid Dispf(on)
Xint on;
X{
X   SetCol(&fImage, on);
X   DrawImage(hp11->RPort, &fImage, fX, INDICY);
X}
X
Xvoid Dispg(on)
Xint on;
X{
X   SetCol(&gImage, on);
X   DrawImage(hp11->RPort, &gImage, gX, INDICY);
X}
X
Xvoid DispUSER(on)
Xint on;
X{
X   SetCol(&USERImage, on);
X   DrawImage(hp11->RPort, &USERImage, USERX, INDICY);
X}
X
Xvoid DispG(on)
Xint on;
X{
X   SetCol(&GImage, on);
X   DrawImage(hp11->RPort, &GImage, GX, INDICY);
X}
X
Xvoid DispRAD(on)
Xint on;
X{
X   SetCol(&RADImage, on);
X   DrawImage(hp11->RPort, &RADImage, RADX, INDICY);
X}
X
Xvoid DispPRGM(on)
Xint on;
X{
X   SetCol(&PRGMImage, on);
X   DrawImage(hp11->RPort, &PRGMImage, PRGMX, INDICY);
X}
X
Xvoid beep(void)
X{
X   DisplayBeep(NULL);
X}
X
Xstatic struct Window *MakeIcon(struct Image *image,
X			       struct BitMap *bm, struct BitMap *tmpbm,
X			       LONG x, LONG y, LONG w, LONG h)
X{
X   register struct Window *win;
X   register ULONG size;
X   static struct NewWindow new_win =
X   { 0, 0, 0, 0, -1, -1, MOUSEBUTTONS | MOUSEMOVE | INACTIVEWINDOW | NOCAREREFRESH,
X     SMART_REFRESH | BORDERLESS | REPORTMOUSE | RMBTRAP,
X     NULL, NULL, NULL, NULL, NULL, 0, 0, 0, 0, WBENCHSCREEN };
X
X   new_win.LeftEdge = x; new_win.TopEdge = y;
X   new_win.Width = w; new_win.Height = h;
X
X   InitBitMap(bm, 2, w, h);
X   size = bm->BytesPerRow * bm->Rows; /* size of 1 plane */
X   bm->Planes[0] = (PLANEPTR)image->ImageData;
X   bm->Planes[1] = (PLANEPTR)(image->ImageData) + size;
X
X   InitBitMap(tmpbm, 2, w, h);
X   if (!(tmpbm->Planes[0] = (PLANEPTR)AllocMem(2 * size, MEMF_CHIP)))
X     return(NULL);
X   tmpbm->Planes[1] = tmpbm->Planes[0] + size;
X
X   if (win = OpenWindow(&new_win)) DrawImage(win->RPort, image, 0, 0);
X   else FreeMem(tmpbm->Planes[0], 2 * size);
X
X   return(win);
X}
X
Xstatic void GetBounds(struct Window *win, LONG *mx, LONG *my,
X		      LONG w, LONG h, LONG wx, LONG wy)
X{
X   struct Screen *scr = win->WScreen;
X
X   *mx = scr->MouseX - wx; *my = scr->MouseY - wy;
X   if (*mx + w > scr->Width) *mx = scr->Width - w;
X   else if (*mx < 0) *mx = 0;
X   if (*my + h > scr->Height) *my = scr->Height - h;
X   else if (*my < 0) *my = 0;
X}
X
Xstatic void SwapImage(struct BitMap *scrbm, struct BitMap *drawing,
X		      struct BitMap *buf, LONG x, LONG y, LONG w, LONG h)
X{
X   BltBitMap(scrbm, x, y, buf, 0, 0, w, h, COPY, 0xff, NULL);
X   BltBitMap(drawing, 0, 0, scrbm, x, y, w, h, COPY, 0xff, NULL);
X   BltBitMap(buf, 0, 0, drawing, 0, 0, w, h, COPY, 0xff, NULL);
X}
X
Xstatic void Iconize(struct Image *image, LONG x, LONG y)
X{
X   register struct Window *win;
X   register struct Screen *scr;
X   register struct IntuiMessage *msg;
X   LONG mx, my, wx, wy;
X   register LONG w, h;
X   ULONG oldsecs = 0, oldmicros = 0;
X   BOOL cont, moved;
X   register BOOL down, wasdown;
X   struct BitMap image_bm, tmpbm;
X
X   w = image->Width; h = image->Height;
X   win = MakeIcon(image, &image_bm, &tmpbm, x, y, w, h);
X   if (win)
X   {
X      scr = win->WScreen;
X      cont = TRUE;
X      down = FALSE;
X      do {
X	 moved = FALSE; wasdown = down;
X	 WaitPort(win->UserPort);
X	 while (msg = (struct IntuiMessage *)GetMsg(win->UserPort))
X	 {
X	    switch (msg->Class)
X	    {
X	       case MOUSEBUTTONS:
X		  if (msg->Code == SELECTUP)
X		  {
X		     if (DoubleClick(oldsecs, oldmicros, msg->Seconds, msg->Micros))
X			cont = FALSE;
X		     else {
X			oldsecs = msg->Seconds;
X			oldmicros = msg->Micros;
X		     }
X		  }
X		  down = (msg->Code == SELECTDOWN);
X		  break;
X	       case INACTIVEWINDOW: down = FALSE; break;
X	       case MOUSEMOVE: moved = TRUE; break;
X	    }
X	    ReplyMsg((struct Message *)msg);
X	 }
X	 if (!wasdown && down)
X	 {
X	    wx = win->MouseX; wy = win->MouseY;
X	    GetBounds(win, &mx, &my, w, h, wx, wy);
X	    LockLayers(&scr->LayerInfo);
X	    SwapImage(&scr->BitMap, &image_bm, &tmpbm, mx, my, w, h);
X	 }
X	 else if (wasdown)
X	    if (down)
X	    {
X	       if (moved)
X	       {
X		  SwapImage(&scr->BitMap, &image_bm, &tmpbm, mx, my, w, h);
X		  GetBounds(win, &mx, &my, w, h, wx, wy);
X		  SwapImage(&scr->BitMap, &image_bm, &tmpbm, mx, my, w, h);
X	       }
X	    }
X	    else
X	    {
X	       SwapImage(&scr->BitMap, &image_bm, &tmpbm, mx, my, w, h);
X	       UnlockLayers(&scr->LayerInfo);
X	       MoveWindow(win, (long)(mx - win->LeftEdge), (long)(my - win->TopEdge));
X	    }
X      } while (cont || down);
X
X      CloseWindow(win);
X      FreeMem(tmpbm.Planes[0], 2 * RASSIZE(w, h));
X   }
X}
X
Xvoid sleep()
X{
X   struct BitMap hp11bitmap;
X   struct RastPort hp11rport;
X   register LONG plsize;
X   register LONG x, y;
X
X   /* Save picture in bitmap */
X   InitBitMap(&hp11bitmap, 2, HP11WIDTH, HP11HEIGHT);
X   plsize = hp11bitmap.BytesPerRow * hp11bitmap.Rows; /* size of 1 plane */
X   /* Allocate enough memory for all planes, initialise plane pointers */
X   if (!(hp11bitmap.Planes[0] = (PLANEPTR)AllocMem(plsize * 2, MEMF_CHIP)))
X      Message("Not enough memory");
X   else
X   {
X      hp11bitmap.Planes[1] = hp11bitmap.Planes[0] + plsize;
X      InitRastPort(&hp11rport);
X      hp11rport.BitMap = &hp11bitmap;
X      ClipBlit(hp11->RPort, HP11X, HP11Y, &hp11rport, 0, 0,
X	       HP11WIDTH, HP11HEIGHT, COPY);
X      Forbid();
X      x = hp11->LeftEdge; y = hp11->TopEdge;
X      Permit();
X      ClearMenuStrip(hp11);
X      CloseWindow(hp11);
X
X      Iconize(&off_image, x, y);
X
X      /* Open the window */
X      hp11new.LeftEdge = x; hp11new.TopEdge = y;
X      if (!(hp11 = OpenWindow(&hp11new)))
X      {
X	 AutoRequest(NULL, &nomemtext, NULL, &canceltext, NULL, NULL, 250, 60);
X	 quit = TRUE;
X      }
X      else {
X	 /* Move picture into window */
X	 BltBitMapRastPort(&hp11bitmap, 0, 0, hp11->RPort, HP11X, HP11Y, HP11WIDTH, HP11HEIGHT, COPY);
X	 FreeMem(hp11bitmap.Planes[0], (long)(hp11bitmap.BytesPerRow * hp11bitmap.Rows * hp11bitmap.Depth));
X	 SetMenuStrip(hp11, hp11menu);
X	 on = TRUE;
X      }
X   }
X}
X
SHAR_EOF
echo "extracting amiga/amiga.h"
sed 's/^X//' << \SHAR_EOF > amiga/amiga.h
X/* These are the computer specific routines which must be rewritten on a
X  different computer */
Xvoid AmigaCleanUp(void); /* CleanUp before exiting, eg make the hp11 disappear,
X  deallocate any memory it took ... This is called by the main CleanUp routine */
X
XBOOL AmigaInit(int, APTR); /* Prepare the HP11 for use (eg display it). This is called
X  by the main Init routine */
X
Xvoid Display(char *); /* Display the argument in the display.
X  Valid chars are 0..9 . , - E r o R u n i g
X  Any other chars are displayed as a space, . & , take no space in the
X  display (which is 11 chars long). */
X
Xint PollKey(int); /* Read a key from the HP11 keyboard.
X  if the argument is TRUE, wait for one to be pressed otherwise return -1 if
X  none is yet available.
X  The value returned is from 0 to 39 (-1 for no key) */
X
X/* Display the various indicators : TRUE to display, FALSE to erase */
Xvoid Dispf(int), Dispg(int), DispUSER(int), DispG(int),
X     DispRAD(int), DispPRGM(int);
X
XBOOL RelKey(void); /* Wait for the latest key (read by PollKey) to be released */
X
X/* Enable/Disable any clipboard style editing facilities (if provided) */
Xvoid EditOn(void), EditOff(void);
X
X/* Provide only if you want seomething special to happen while the HP11 is
X  off. There is a default version in hp11.c */
Xvoid sleep(void);
X
X/* Wait n 50ths of a second. Here simply defined ... */
X#define Wait50 Delay
Xvoid Delay(long);
X
X/* These routines are actually in menus.c */
Xvoid MenusOn(void), MenusOff(void);
X
X
SHAR_EOF
echo "extracting amiga/cbio.c"
sed 's/^X//' << \SHAR_EOF > amiga/cbio.c
X#include <proto/exec.h>
X#include <exec/io.h>
X#include <devices/clipboard.h>
X#include <iff/iff.h>
X#include "user/cbio.h"
X
X#include <string.h>
X
X#define FTXT MakeID('F','T','X','T')
X#define CHRS MakeID('C','H','R','S')
X
Xstruct IOClipReq *clipboardIO;
Xstruct MsgPort *clipboardMsgPort;
X
Xlong CBOpen(long unit)
X{
X   long error;
X
X   if ((clipboardMsgPort = CreatePort(0, 0)) == 0) return(-1);
X
X   if ((clipboardIO = (struct IOClipReq *)CreateExtIO(clipboardMsgPort, sizeof(struct IOClipReq))) == 0) {
X      DeletePort(clipboardMsgPort);
X      return(-1);
X   }
X
X   if ((error = OpenDevice("clipboard.device", unit, (struct IORequest *)clipboardIO, 0)) != 0) {
X      DeleteExtIO((struct IORequest *)clipboardIO, sizeof(struct IOClipReq));
X      DeletePort(clipboardMsgPort);
X      return(error);
X   }
X
X   return(0);
X}
X
Xvoid CBClose(void)
X{
X   if (clipboardIO) {
X      CloseDevice((struct IORequest *)clipboardIO);
X      DeleteExtIO((struct IORequest *)clipboardIO, sizeof(struct IOClipReq));
X   }
X   if (clipboardMsgPort) DeletePort(clipboardMsgPort);
X}
X
Xvoid CBWrite(void *data, int length)
X{
X   clipboardIO->io_Command = CMD_WRITE;
X   clipboardIO->io_Data = data;
X   clipboardIO->io_Length = length;
X   DoIO((struct IORequest *)clipboardIO);
X}
X
X
Xvoid CBCut(char *text)
X{
X   ID writeID;
X   long ifflen;
X   int len = strlen(text);
X
X   clipboardIO->io_Offset = 0;
X   clipboardIO->io_ClipID = 0;
X
X   writeID = FORM;
X   CBWrite(&writeID, 4);
X
X   ifflen = len + 12;
X   CBWrite(&ifflen, 4);
X
X   writeID = FTXT;
X   CBWrite(&writeID, 4);
X
X   writeID = CHRS;
X   CBWrite(&writeID, 4);
X
X   CBWrite(&len, 4);
X   CBWrite(text, len);
X
X   clipboardIO->io_Command = CMD_UPDATE;
X   DoIO((struct IORequest *)clipboardIO);
X}
X
XBYTE *CBRead(void *data, int length)
X{
X   clipboardIO->io_Command = CMD_READ;
X   clipboardIO->io_Data = data;
X   clipboardIO->io_Length = length;
X   DoIO((struct IORequest *)clipboardIO);
X
X   return(data);
X}
X
XBOOL CBPaste(char *string)
X{
X   long length;
X   BOOL success = FALSE;
X   ID check;
X
X   clipboardIO->io_ClipID = 0;
X   clipboardIO->io_Offset = 0;
X
X   CBRead(&check, 4);
X   if (check == FORM) {
X
X      CBRead(&check, 4);
X      CBRead(&check, 4);
X      if (check == FTXT) {
X
X	 CBRead(&check, 4);
X	 if (check == CHRS) {
X
X	    CBRead(&length, 4);
X	    CBRead(string, length);
X	    string[length] = '\0';
X	    success = TRUE;
X	 }
X      }
X   }
X
X   while (clipboardIO->io_Actual != 0)
X      CBRead(NULL, 1 << 30);
X
X   return(success);
X}
SHAR_EOF
echo "extracting amiga/cbio.h"
sed 's/^X//' << \SHAR_EOF > amiga/cbio.h
Xextern long __stdargs CBOpen(long);
Xextern void __stdargs CBClose(void);
Xextern void __stdargs CBCut(char *);
Xextern BOOL __stdargs CBPaste(char *);
X
SHAR_EOF
echo "extracting amiga/chars.c"
sed 's/^X//' << \SHAR_EOF > amiga/chars.c
X/* this defines the character shapes */
X#include "exec/types.h"
X#include "intuition/intuition.h"
X
X/* First the shape of the seven segments + point & comma.
X  They are defined in a 14x13 box and are drawn by a series of lines.
X  The offsets are relative to the top left corner of this box */
Xstatic WORD top[] = {
X   4,0,
X   10,0,
X   9,1,
X   5,1
X};
Xstatic WORD ctr[] = {
X   4,6,
X   10,6,
X   10,7,
X   4,7,
X};
Xstatic WORD bottom[] = {
X   5,12,
X   9,12,
X   10,13,
X   4,13
X};
Xstatic WORD tl[] = {
X   3,1,
X   3,6,
X   4,5,
X   4,1
X};
Xstatic WORD tr[] = {
X   11,1,
X   11,6,
X   10,5,
X   10,1
X};
Xstatic WORD bl[] = {
X   3,7,
X   3,12,
X   4,12,
X   4,8
X};
Xstatic WORD br[] = {
X   11,7,
X   11,12,
X   10,12,
X   10,8
X};
Xstatic WORD pt[] = {
X   -1,12,
X   0,12,
X   0,13,
X   -1,13
X};
Xstatic WORD com[] = {
X   0,14,
X   -1,14,
X   -1,15,
X   -2,15
X};
X
X/* Character definitions, they are composed of the seven segments */
Xstatic struct Border zero[] = {
X{ 0, 0, 1, 2, JAM1, 4, top, &zero[1] },
X{ 0, 0, 1, 2, JAM1, 4, tl, &zero[2] },
X{ 0, 0, 1, 2, JAM1, 4, tr, &zero[3] },
X{ 0, 0, 1, 2, JAM1, 4, bl, &zero[4] },
X{ 0, 0, 1, 2, JAM1, 4, br, &zero[5] },
X{ 0, 0, 1, 2, JAM1, 4, bottom, NULL }
X};
Xstatic struct Border one[] = {
X{ 0, 0, 1, 2, JAM1, 4, tr, &one[1] },
X{ 0, 0, 1, 2, JAM1, 4, br, NULL }
X};
Xstatic struct Border two[] = {
X{ 0, 0, 1, 2, JAM1, 4, top, &two[1] },
X{ 0, 0, 1, 2, JAM1, 4, tr, &two[2] },
X{ 0, 0, 1, 2, JAM1, 4, ctr, &two[3] },
X{ 0, 0, 1, 2, JAM1, 4, bl, &two[4] },
X{ 0, 0, 1, 2, JAM1, 4, bottom, NULL }
X};
Xstatic struct Border three[] = {
X{ 0, 0, 1, 2, JAM1, 4, top, &three[1] },
X{ 0, 0, 1, 2, JAM1, 4, ctr, &three[2] },
X{ 0, 0, 1, 2, JAM1, 4, bottom, &three[3] },
X{ 0, 0, 1, 2, JAM1, 4, tr, &three[4] },
X{ 0, 0, 1, 2, JAM1, 4, br, NULL }
X};
Xstatic struct Border four[] = {
X{ 0, 0, 1, 2, JAM1, 4, tr, &four[1] },
X{ 0, 0, 1, 2, JAM1, 4, tl, &four[2] },
X{ 0, 0, 1, 2, JAM1, 4, br, &four[3] },
X{ 0, 0, 1, 2, JAM1, 4, ctr, NULL }
X};
Xstatic struct Border five[] = {
X{ 0, 0, 1, 2, JAM1, 4, top, &five[1] },
X{ 0, 0, 1, 2, JAM1, 4, ctr, &five[2] },
X{ 0, 0, 1, 2, JAM1, 4, bottom, &five[3] },
X{ 0, 0, 1, 2, JAM1, 4, tl, &five[4] },
X{ 0, 0, 1, 2, JAM1, 4, br, NULL }
X};
Xstatic struct Border six[] = {
X{ 0, 0, 1, 2, JAM1, 4, top, &six[1] },
X{ 0, 0, 1, 2, JAM1, 4, ctr, &six[2] },
X{ 0, 0, 1, 2, JAM1, 4, bottom, &six[3] },
X{ 0, 0, 1, 2, JAM1, 4, tl, &six[4] },
X{ 0, 0, 1, 2, JAM1, 4, bl, &six[5] },
X{ 0, 0, 1, 2, JAM1, 4, br, NULL }
X};
Xstatic struct Border seven[] = {
X{ 0, 0, 1, 2, JAM1, 4, top, &seven[1] },
X{ 0, 0, 1, 2, JAM1, 4, tr, &seven[2] },
X{ 0, 0, 1, 2, JAM1, 4, br, NULL }
X};
Xstatic struct Border eight[] = {
X{ 0, 0, 1, 2, JAM1, 4, top, &eight[1] },
X{ 0, 0, 1, 2, JAM1, 4, ctr, &eight[2] },
X{ 0, 0, 1, 2, JAM1, 4, bottom, &eight[3] },
X{ 0, 0, 1, 2, JAM1, 4, tl, &eight[4] },
X{ 0, 0, 1, 2, JAM1, 4, tr, &eight[5] },
X{ 0, 0, 1, 2, JAM1, 4, bl, &eight[6] },
X{ 0, 0, 1, 2, JAM1, 4, br, NULL }
X};
Xstatic struct Border nine[] = {
X{ 0, 0, 1, 2, JAM1, 4, top, &nine[1] },
X{ 0, 0, 1, 2, JAM1, 4, ctr, &nine[2] },
X{ 0, 0, 1, 2, JAM1, 4, bottom, &nine[3] },
X{ 0, 0, 1, 2, JAM1, 4, tl, &nine[4] },
X{ 0, 0, 1, 2, JAM1, 4, tr, &nine[5] },
X{ 0, 0, 1, 2, JAM1, 4, br, NULL }
X};
Xstatic struct Border minus[] = {
X{ 0, 0, 1, 2, JAM1, 4, ctr, NULL }
X};
Xstatic struct Border E[] = {
X{ 0, 0, 1, 2, JAM1, 4, top, &E[1] },
X{ 0, 0, 1, 2, JAM1, 4, ctr, &E[2] },
X{ 0, 0, 1, 2, JAM1, 4, bottom, &E[3] },
X{ 0, 0, 1, 2, JAM1, 4, tl, &E[4] },
X{ 0, 0, 1, 2, JAM1, 4, bl, NULL }
X};
Xstatic struct Border r[] = {
X{ 0, 0, 1, 2, JAM1, 4, ctr, &r[1] },
X{ 0, 0, 1, 2, JAM1, 4, bl, NULL }
X};
Xstatic struct Border o[] = {
X{ 0, 0, 1, 2, JAM1, 4, ctr, &o[1] },
X{ 0, 0, 1, 2, JAM1, 4, bottom, &o[2] },
X{ 0, 0, 1, 2, JAM1, 4, bl, &o[3] },
X{ 0, 0, 1, 2, JAM1, 4, br, NULL }
X};
Xstatic struct Border R[] = {
X{ 0, 0, 1, 2, JAM1, 4, top, &R[1] },
X{ 0, 0, 1, 2, JAM1, 4, tl, NULL }
X};
Xstatic struct Border u[] = {
X{ 0, 0, 1, 2, JAM1, 4, tl, &u[1] },
X{ 0, 0, 1, 2, JAM1, 4, tr, &u[2] },
X{ 0, 0, 1, 2, JAM1, 4, ctr, NULL }
X};
Xstatic struct Border n[] = {
X{ 0, 0, 1, 2, JAM1, 4, top, &n[1] },
X{ 0, 0, 1, 2, JAM1, 4, tl, &n[2] },
X{ 0, 0, 1, 2, JAM1, 4, tr, NULL },
X};
Xstatic struct Border i[] = {
X{ 0, 0, 1, 2, JAM1, 4, tr, NULL },
X};
Xstatic struct Border point[] = {
X{ 0, 0, 1, 2, JAM1, 4, pt, NULL },
X};
Xstatic struct Border comma[] = {
X{ 0, 0, 1, 2, JAM1, 4, pt, &comma[1] },
X{ 0, 0, 1, 2, JAM1, 4, com, NULL }
X};
Xstatic struct Border P[] = {
X{ 0, 0, 1, 2, JAM1, 4, top, &P[1] },
X{ 0, 0, 1, 2, JAM1, 4, ctr, &P[2] },
X{ 0, 0, 1, 2, JAM1, 4, tr, &P[3] },
X{ 0, 0, 1, 2, JAM1, 4, tl, &P[4] },
X{ 0, 0, 1, 2, JAM1, 4, bl, NULL }
X};
X
X/* The character array, visible to the exterior */
Xstruct Border *hp11char[] = {
X  zero, one, two, three, four, five, six, seven, eight, nine,
X  minus, E, r, o, R, u, n, i, nine /* g */, point, comma, P };
X
SHAR_EOF
echo "extracting amiga/chip.c"
sed 's/^X//' << \SHAR_EOF > amiga/chip.c
X#include "exec/types.h"
X
XUWORD chip fData[] = {
X   0x2000, 0x4000, 0xE000, 0x4000, 0x4000, 0x4000,
X   0xDFFF, 0xBFFF, 0x1FFF, 0xBFFF, 0xBFFF, 0xBFFF
X};
X/*   X */
X/*  X  */
X/* XXX */
X/*  X  */
X/*  X  */
X/*  X  */
X
XUWORD chip gData[] = {
X   0x7000, 0x9000, 0x9000, 0x7000, 0x1000, 0xE000,
X   0x8FFF, 0x6FFF, 0x6FFF, 0x8FFF, 0xEFFF, 0x1FFF
X};
X/*  XXX */
X/* X  X */
X/* X  X */
X/*  XXX */
X/*    X */
X/* XXX	*/
X
XUWORD chip GData[] = {
X   0x6000, 0x9000, 0x8000, 0xB000, 0x9000, 0x6000,
X   0x9FFF, 0x6FFF, 0x7FFF, 0x4FFF, 0x6FFF, 0x9FFF
X};
X/*  XX	*/
X/* X  X */
X/* X	*/
X/* X XX */
X/* X  X */
X/*  XX	*/
X
XUWORD chip RADData[] = {
X   0xE338, 0x94A4, 0x94A4, 0xE7A4, 0xA4A4, 0x94B8,
X   0x1CC7, 0x6B5B, 0x6B5B, 0x185B, 0x5B5B, 0x6B47
X};
X/* XXX	 XX  XXX  */
X/* X  X X  X X	X */
X/* X  X X  X X	X */
X/* XXX	XXXX X	X */
X/* X X	X  X X	X */
X/* X  X X  X XXX  */
X
XUWORD chip PRGMData[] = {
X   0xE719, 0x2000,  0x94A5, 0xE000,  0x94A1, 0x2000,  0xE72D, 0x2000,  0x8525, 0x2000,	0x8499, 0x2000,
X   0x18E6, 0xDFFF,  0x6B5A, 0x1FFF,  0x6B5E, 0xDFFF,  0x18D2, 0xDFFF,  0x7ADA, 0xDFFF,	0x7B66, 0xDFFF
X};
X/* XXX	XXX   XX  X  X */
X/* X  X X  X X	X XXXX */
X/* X  X X  X X	  X  X */
X/* XXX	XXX  X XX X  X */
X/* X	X X  X	X X  X */
X/* X	X  X  XX  X  X */
X
XUWORD chip USERData[] = {
X   0x933D, 0xC000,  0x94A1, 0x2000,  0x9239, 0x2000,  0x9121, 0xC000,  0x94A1, 0x4000,	0x633D, 0x2000,
X   0x6CC2, 0x3FFF,  0x6B5E, 0xDFFF,  0x6DC6, 0xDFFF,  0x6EDE, 0x3FFF,  0x6B5E, 0xBFFF,	0x9CC2, 0xDFFF
X};
X
X/* X  X  XX  XXXX XXX  */
X/* X  X X  X X	  X  X */
X/* X  X  X   XXX  X  X */
X/* X  X   X  X	  XXX  */
X/* X  X X  X X	  X X  */
X/*  XX	 XX  XXXX X  X */
X
XUWORD chip prog_image_data[] = {
X   0,	0,   0,   0,
X   0,	0,   0,   0,
X   0,	0,   0,   0,
X   4095,   65247,   65535,   32768,
X   4095,   63683,   65535,   32768,
X   4095,   57728,   65535,   32768,
X   4095,   49536,   16383,   32768,
X   4095,   33536,   8191,   32768,
X   4095,   33536,   8191,   32768,
X   4095,   1536,   4095,   32768,
X   4095,   1920,   4095,   32768,
X   4094,   3279,   51199,   32768,
X   4094,   3276,   26623,   32768,
X   4094,   6552,   14335,   32768,
X   4094,   6552,   14335,   32768,
X   4094,   13080,   26623,   32768,
X   4094,   13104,   51199,   32768,
X   4095,   63,	 36863,   32768,
X   4095,   48,	 4095,	 32768,
X   4095,   32864,   8191,   32768,
X   4095,   32864,   16383,   32768,
X   4095,   49248,   32767,   32768,
X   4095,   61633,   65535,   32768,
X   4095,   64711,   65535,   32768,
X   4095,   65247,   65535,   32768,
X   0,	0,   0,   0,
X   4095,   65535,   65535,   32768,
X   4095,   65535,   65535,   32768,
X   4095,   65535,   65535,   32768,
X   4095,   65535,   65535,   32768,
X   4095,   65535,   65535,   32768,
X   4095,   65535,   65535,   32768,
X   4095,   65535,   65535,   32768,
X   4095,   65535,   65535,   32768,
X   4095,   65535,   65535,   32768,
X   4095,   65535,   65535,   32768,
X   4095,   65535,   65535,   32768,
X   4095,   65535,   65535,   32768,
X   4095,   65535,   65535,   32768,
X   0,	0,   0,   0,
X   0,	0,   0,   0,
X   0,	0,   0,   0,
X
X   65535,   65535,   65535,   63488,
X   65535,   65535,   65535,   63488,
X   65535,   65535,   65535,   63488,
X   61440,   480,   0,	30720,
X   61440,   2044,   0,	 30720,
X   61440,   8191,   0,	 30720,
X   61440,   16383,   49152,   30720,
X   61440,   32767,   57344,   30720,
X   61440,   32767,   57344,   30720,
X   61440,   65535,   61440,   30720,
X   61440,   65535,   61440,   30720,
X   61441,   65535,   63488,   30720,
X   61441,   65535,   63488,   30720,
X   61441,   65535,   63488,   30720,
X   61441,   65535,   63488,   30720,
X   61441,   65535,   63488,   30720,
X   61441,   65535,   63488,   30720,
X   61440,   65535,   61440,   30720,
X   61440,   65535,   61440,   30720,
X   61440,   32767,   57344,   30720,
X   61440,   32767,   49152,   30720,
X   61440,   16383,   32768,   30720,
X   61440,   4094,   0,	 30720,
X   61440,   1016,   0,	 30720,
X   61440,   480,   0,	30720,
X   65535,   65535,   65535,   63488,
X   61440,   0,	 0,   30720,
X   61440,   0,	 0,   30720,
X   61440,   0,	 0,   30720,
X   61694,   16259,   49400,   30720,
X   61539,   6342,   24972,   30720,
X   61539,   6348,   13056,   30720,
X   61566,   8076,   13084,   30720,
X   61536,   6540,   13068,   30720,
X   61536,   6342,   24972,   30720,
X   61688,   14435,   49404,   30720,
X   61440,   0,	 0,   30720,
X   61440,   0,	 0,   30720,
X   61440,   0,	 0,   30720,
X   65535,   65535,   65535,   63488,
X   65535,   65535,   65535,   63488,
X   65535,   65535,   65535,   63488,
X};
X
XUWORD chip off_image_data[] = {
X   0,
X   0,
X   0,
X   0,
X   0,
X   0,
X   0,
X   0,
X   0,
X   0,
X   0,
X   0,
X   4095,
X   65247,
X   65535,
X   32768,
X   4095,
X   63683,
X   65535,
X   32768,
X   4095,
X   57728,
X   65535,
X   32768,
X   4095,
X   49536,
X   16383,
X   32768,
X   4095,
X   33536,
X   8191,
X   32768,
X   4095,
X   33536,
X   8191,
X   32768,
X   4095,
X   1536,
X   4095,
X   32768,
X   4095,
X   1920,
X   4095,
X   32768,
X   4094,
X   3279,
X   51199,
X   32768,
X   4094,
X   3276,
X   26623,
X   32768,
X   4094,
X   6552,
X   14335,
X   32768,
X   4094,
X   6552,
X   14335,
X   32768,
X   4094,
X   13080,
X   26623,
X   32768,
X   4094,
X   13104,
X   51199,
X   32768,
X   4095,
X   63,
X   36863,
X   32768,
X   4095,
X   48,
X   4095,
X   32768,
X   4095,
X   32864,
X   8191,
X   32768,
X   4095,
X   32864,
X   16383,
X   32768,
X   4095,
X   49248,
X   32767,
X   32768,
X   4095,
X   61633,
X   65535,
X   32768,
X   4095,
X   64711,
X   65535,
X   32768,
X   4095,
X   65247,
X   65535,
X   32768,
X   0,
X   0,
X   0,
X   0,
X   4095,
X   65535,
X   65535,
X   32768,
X   4032,
X   32259,
X   57351,
X   32768,
X   3840,
X   30723,
X   49155,
X   32768,
X   3128,
X   25027,
X   49635,
X   32768,
X   4088,
X   32707,
X   50175,
X   32768,
X   4088,
X   32707,
X   50175,
X   32768,
X   4088,
X   32707,
X   50175,
X   32768,
X   4088,
X   32707,
X   50175,
X   32768,
X   4088,
X   32707,
X   50175,
X   32768,
X   4088,
X   32707,
X   49635,
X   32768,
X   4088,
X   32707,
X   49155,
X   32768,
X   4088,
X   32707,
X   57351,
X   32768,
X   4095,
X   65535,
X   65535,
X   32768,
X   0,
X   0,
X   0,
X   0,
X   0,
X   0,
X   0,
X   0,
X   0,
X   0,
X   0,
X   0,
X   65535,
X   65535,
X   65535,
X   63488,
X   65535,
X   65535,
X   65535,
X   63488,
X   65535,
X   65535,
X   65535,
X   63488,
X   61440,
X   288,
X   0,
X   30720,
X   61440,
X   1852,
X   0,
X   30720,
X   61440,
X   7807,
X   0,
X   30720,
X   61440,
X   15999,
X   49152,
X   30720,
X   61440,
X   31999,
X   57344,
X   30720,
X   61440,
X   31999,
X   57344,
X   30720,
X   61440,
X   63999,
X   61440,
X   30720,
X   61440,
X   63615,
X   61440,
X   30720,
X   61441,
X   62256,
X   14336,
X   30720,
X   61441,
X   62259,
X   38912,
X   30720,
X   61441,
X   58983,
X   51200,
X   30720,
X   61441,
X   58983,
X   51200,
X   30720,
X   61441,
X   52455,
X   38912,
X   30720,
X   61441,
X   52431,
X   14336,
X   30720,
X   61440,
X   65472,
X   28672,
X   30720,
X   61440,
X   65487,
X   61440,
X   30720,
X   61440,
X   32671,
X   57344,
X   30720,
X   61440,
X   32671,
X   49152,
X   30720,
X   61440,
X   16287,
X   32768,
X   30720,
X   61440,
X   3902,
X   0,
X   30720,
X   61440,
X   824,
X   0,
X   30720,
X   61440,
X   288,
X   0,
X   30720,
X   65535,
X   65535,
X   65535,
X   63488,
X   61440,
X   0,
X   0,
X   30720,
X   61503,
X   33276,
X   8184,
X   30720,
X   61695,
X   34812,
X   16380,
X   30720,
X   62407,
X   40508,
X   15900,
X   30720,
X   61447,
X   32828,
X   15360,
X   30720,
X   61447,
X   32828,
X   15360,
X   30720,
X   61447,
X   32828,
X   15360,
X   30720,
X   61447,
X   32828,
X   15360,
X   30720,
X   61447,
X   32828,
X   15360,
X   30720,
X   61447,
X   32828,
X   15900,
X   30720,
X   61447,
X   32828,
X   16380,
X   30720,
X   61447,
X   32828,
X   8184,
X   30720,
X   61440,
X   0,
X   0,
X   30720,
X   65535,
X   65535,
X   65535,
X   63488,
X   65535,
X   65535,
X   65535,
X   63488,
X   65535,
X   65535,
X   65535,
X   63488,
X};
X
X
SHAR_EOF
echo "End of archive 1 (of 3)"
# if you want to concatenate archives, remove anything after this line
exit