/*************************************************************
 *************************************************************
 ****                                                     ****
 ****   6 5 1 0  -  D e v e l o p e r s  -  P a c k e t   ****
 ****                                                     ****
 ****        C  R  O  S  S  A  S  S     V  1  .  0        ****
 ****        -------------------------------------        ****
 ****                                                     ****
 ****         programmiert von Christian Krenner          ****
 ****     (C)opyright 1992 Markt & Technik Verlag AG      ****
 ****                                                     ****
 *************************************************************
 *************************************************************/

/************
 * includes *
 ************/

#include <exec/exec.h>
#include <intuition/intuition.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>
#include <ctype.h>

#include <dos/dosasl.h>
#include <libraries/asl.h>
#include <clib/asl_protos.h>
#include <clib/dos_protos.h>
#include <intuition/intuitionbase.h>

/*******************
 * neue Strukturen *
 *******************/

struct Label
{
   char name[32];
   unsigned int wert;
   unsigned int aufruf;
   unsigned int macro;
};

struct Macro
{
   char name[32];
   char *source;
   char paramcount;
   unsigned long lenght;
   unsigned int aufruf;
};

struct MacroStack
{
   char *pointer;
   char *endbuffer;
   long actlenght;
   char paramcount;
   unsigned int params[10];
   BOOL defd[10];
   long lineafter;
   unsigned int number;
   unsigned int aufruf;
};

struct IncludeStack
{
   char lastfile[256];
   long lineafter;
};

struct Block
{
   unsigned int begin;
   unsigned int end;
   char name[32];
   unsigned int labels;
};

struct Einstellungen
{
   unsigned long macromemlenght;
   unsigned long macrotablelenght;
   unsigned long labellenght;
   unsigned int delay;
   BOOL sort;
   unsigned char converttable[256];
};

/********************************
 * globale Strukturen für Menüs *
 ********************************/

struct TextAttr Font =
{ (STRPTR)"topaz.font", TOPAZ_EIGHTY, FS_NORMAL, FPF_ROMFONT };
struct IntuiText DateiUebertragenText =
{ 0, 1, JAM2, 1, 1, &Font, (UBYTE *)"Übertragen", NULL };
struct IntuiText DateiInformationText =
{ 0, 1, JAM2, 1, 1, &Font, (UBYTE *)"Über ...", NULL };
struct IntuiText DateiEndeText =
{ 0, 1, JAM2, 1, 1, &Font, (UBYTE *)"Ende", NULL };
struct IntuiText TabellenLabelsText =
{ 0, 1, JAM2, 1, 1, &Font, (UBYTE *)"Labels", NULL };
struct IntuiText TabellenMakrosText =
{ 0, 1, JAM2, 1, 1, &Font, (UBYTE *)"Makros", NULL };
struct IntuiText TabellenBloeckeText =
{ 0, 1, JAM2, 1, 1, &Font, (UBYTE *)"Blöcke", NULL };
struct IntuiText TabellenMnemonicsText =
{ 0, 1, JAM2, 1, 1, &Font, (UBYTE *)"Mnemonics", NULL };
struct IntuiText EinstAendernText =
{ 0, 1, JAM2, 1, 1, &Font, (UBYTE *)"Ändern", NULL };
struct IntuiText EinstSpeichernText =
{ 0, 1, JAM2, 1, 1, &Font, (UBYTE *)"Speichern", NULL };
struct IntuiText EinstLadenText =
{ 0, 1, JAM2, 1, 1, &Font, (UBYTE *)"Laden", NULL };
struct IntuiText EinstKLadenText =
{ 0, 1, JAM2, 1, 1, &Font, (UBYTE *)"KonvTab laden", NULL };
struct IntuiText DruckenSText =
{ 0, 1, JAM2, 1, 1, &Font, (UBYTE *)"Quelldatei", NULL };
struct IntuiText DruckenLabelText =
{ 0, 1, JAM2, 1, 1, &Font, (UBYTE *)"Labels", NULL };
struct IntuiText DruckenMakroText =
{ 0, 1, JAM2, 1, 1, &Font, (UBYTE *)"Makros", NULL };
struct IntuiText DruckenBloeckeText =
{ 0, 1, JAM2, 1, 1, &Font, (UBYTE *)"Blöcke", NULL };
struct MenuItem DruckenBloecke =
{ NULL, 1, 31, 152, 10, ITEMTEXT | COMMSEQ | HIGHCOMP | ITEMENABLED,
  0L, (APTR)&DruckenBloeckeText, NULL, '1', NULL, 0, };
struct MenuItem DruckenMakros =
{ &DruckenBloecke, 1, 21, 152, 10, ITEMTEXT | COMMSEQ | HIGHCOMP | ITEMENABLED,
  0L, (APTR)&DruckenMakroText, NULL, '2', NULL, 0, };
struct MenuItem DruckenLabels =
{ &DruckenMakros, 1, 11, 152, 10, ITEMTEXT | COMMSEQ | HIGHCOMP | ITEMENABLED,
  0L, (APTR)&DruckenLabelText, NULL, '3', NULL, 0, };
struct MenuItem DruckenSource =
{ &DruckenLabels, 1, 1, 152, 10, ITEMTEXT | COMMSEQ | HIGHCOMP | ITEMENABLED,
  0L, (APTR)&DruckenSText, NULL, '4', NULL, 0, };
struct MenuItem EinstKLaden =
{ NULL, 1, 31, 152, 10, ITEMTEXT | COMMSEQ | HIGHCOMP | ITEMENABLED,
  0L, (APTR)&EinstKLadenText, NULL, 'K', NULL, 0, };
struct MenuItem EinstLaden =
{ &EinstKLaden, 1, 21, 152, 10, ITEMTEXT | COMMSEQ | HIGHCOMP | ITEMENABLED,
  0L, (APTR)&EinstLadenText, NULL, 'O', NULL, 0, };
struct MenuItem EinstSpeichern =
{ &EinstLaden, 1, 11, 152, 10, ITEMTEXT | COMMSEQ | HIGHCOMP | ITEMENABLED,
  0L, (APTR)&EinstSpeichernText, NULL, 'S', NULL, 0, };
struct MenuItem EinstAendern =
{ &EinstSpeichern, 1, 1, 152, 10, ITEMTEXT | COMMSEQ | HIGHCOMP | ITEMENABLED,
  0L, (APTR)&EinstAendernText, NULL, 'A', NULL, 0, };
struct MenuItem TabellenMnemonics =
{ NULL, 1, 31, 152, 10, ITEMTEXT | COMMSEQ | HIGHCOMP | ITEMENABLED,
  0L, (APTR)&TabellenMnemonicsText, NULL, 'N', NULL, 0, };
struct MenuItem TabellenBloecke =
{ &TabellenMnemonics, 1, 21, 152, 10, ITEMTEXT | COMMSEQ | HIGHCOMP | ITEMENABLED,
  0L, (APTR)&TabellenBloeckeText, NULL, 'B', NULL, 0, };
struct MenuItem TabellenMakros =
{ &TabellenBloecke, 1, 11, 152, 10, ITEMTEXT | COMMSEQ | HIGHCOMP | ITEMENABLED,
  0L, (APTR)&TabellenMakrosText, NULL, 'M', NULL, 0, };
struct MenuItem TabellenLabels =
{ &TabellenMakros, 1, 1, 152, 10, ITEMTEXT | COMMSEQ | HIGHCOMP | ITEMENABLED,
  0L, (APTR)&TabellenLabelsText, NULL, 'L', NULL, 0, };
struct MenuItem DateiEnde =
{ NULL, 1, 21, 152, 10, ITEMTEXT | COMMSEQ | HIGHCOMP | ITEMENABLED,
  0L, (APTR)&DateiEndeText, NULL, 'Q', NULL, 0, };
struct MenuItem DateiInformation =
{ &DateiEnde, 1, 11, 152, 10, ITEMTEXT | COMMSEQ | HIGHCOMP | ITEMENABLED,
  0L, (APTR)&DateiInformationText, NULL, '?', NULL, 0, };
struct MenuItem DateiUebertragen =
{ &DateiInformation, 1, 1, 152, 10, ITEMTEXT | COMMSEQ | HIGHCOMP | ITEMENABLED,
  0L, (APTR)&DateiUebertragenText, NULL, 'T', NULL, 0, };
struct Menu MenuDrucken =
{ NULL, 314, 0, 88, 0, MENUENABLED, (BYTE *)" Drucken",
  &DruckenSource };
struct Menu MenuEinstellungen =
{ &MenuDrucken, 178, 0, 136, 0, MENUENABLED, (BYTE *)" Einstellungen",
  &EinstAendern };
struct Menu MenuTabellen =
{ &MenuEinstellungen, 82, 0, 96, 0, MENUENABLED, (BYTE *)" Tabellen",
  &TabellenLabels };
struct Menu MenuDatei =
{ &MenuTabellen, 10, 0, 72, 0, MENUENABLED, (BYTE *)" Datei",
  &DateiUebertragen };

/**************************************
 * globale Strukturen für Hauptwindow *
 **************************************/

SHORT Werte1[] =
{ 0, 62, 0, 0, 376, 0 };
SHORT Werte2[] =
{ 376, 1, 376, 62, 1, 62 };
SHORT GWerte1[] =
{ 0, 11, 0, 0, 180, 0 };
SHORT GWerte2[] =
{ 180, 1, 180, 11, 1, 11 };
struct Border GadgetBorder2 =
{ 0, 0, 1, 0, JAM1, 3, GWerte2, NULL };
struct Border GadgetBorder1 =
{ 0, 0, 2, 0, JAM1, 3, GWerte1, &GadgetBorder2 };
struct Border Border2 =
{ 16, 24, 2, 0, JAM1, 3, Werte2, NULL };
struct Border Border1 =
{ 16, 24, 1, 0, JAM1, 3, Werte1, &Border2 };
struct IntuiText GadgetText2 =
{ 1, 0, JAM2, 62, 2, &Font, (UBYTE *)" Stop ", NULL };
struct IntuiText GadgetText1 =
{ 1, 0, JAM2, 66, 2, &Font, (UBYTE *)"Start", NULL };
struct IntuiText Text7 =
{ 3, 0, JAM2, 20, 76, NULL,
  (UBYTE *)"                                             ", NULL };
struct IntuiText Text6 =
{ 1, 0, JAM2, 20, 66, &Font,
  (UBYTE *)"Zeile: 000000  Zeilen insg: 000000   Pass: -", &Text7 };
struct IntuiText Text5 =
{ 1, 0, JAM2, 20, 56, &Font,
  (UBYTE *)"Anzahl Symbole: 00000   Anzahl Makros: 00000", &Text6 };
struct IntuiText Text4 =
{ 1, 0, JAM2, 20, 46, &Font,
  (UBYTE *)"Code: $0000 - $0000     Länge: 00000 Byte", &Text5 };
struct IntuiText Text3 =
{ 1, 0, JAM2, 20, 36, &Font,
  (UBYTE *)"Objektdatei:                                 ", &Text4 };
struct IntuiText Text2 =
{ 1, 0, JAM2, 20, 26, &Font, 
  (UBYTE *)"Quelldatei:                                  ", &Text3 };
struct IntuiText Text1 =
{ 3, 0, JAM2, 20, 14, &Font, (UBYTE *)"Status:", &Text2 };
struct Gadget Gadget1 =
{ NULL, 114, 90, 181, 12, GADGHCOMP, RELVERIFY, BOOLGADGET,
  &GadgetBorder1, NULL, &GadgetText1, NULL, NULL, 1, NULL };
struct NewWindow MainNewWindow =
{ 116, 50, 408, 108, -1, -1, CLOSEWINDOW | GADGETUP | MENUPICK,
  WINDOWDEPTH | WINDOWDRAG | WINDOWCLOSE | SMART_REFRESH | ACTIVATE,
  &Gadget1, NULL, (UBYTE *)"CrossAss V1.0, © 1994 MagnaMedia Verlag AG",
  NULL, NULL, 116, 50, 408, 140, WBENCHSCREEN };

/*****************************************
 * globale Strukturen für Tabellenwindow *
 *****************************************/

char TaText[15][51];
struct IntuiText TaIntuiText[15];
struct IntuiText TaTText =
{ 1, 0, JAM2, 8, 0, &Font, NULL, NULL };
SHORT TaWerte1[] =
{ 0, 124, 0, 0, 404, 0 };
SHORT TaWerte2[] =
{ 404, 1, 404, 124, 1, 124 };
SHORT TaWerte3[] =
{ 0, 8, 0, 0, 20, 0 };
SHORT TaWerte4[] =
{ 20, 1, 20, 8, 1, 8 };
SHORT TaWerte5[] =
{ 0, 106, 0, 0, 20, 0 };
SHORT TaWerte6[] =
{ 20, 1, 20, 106, 1, 106 };
SHORT TaWerte7[] =
{ 4, 5, 11, 2, 17, 5 };
SHORT TaWerte8[] =
{ 4, 3, 11, 6, 17, 3 };
struct IntuiText TaText1 =
{ 3, 0, JAM2, 8, 12, &Font,
  (UBYTE *)"                                                  ", NULL };
struct Image TaImage1;
struct Border TaBorder8 =
{ 0, 0, 1, 0, JAM1, 3, TaWerte8, NULL };
struct Border TaBorder7 =
{ 0, 0, 1, 0, JAM1, 3, TaWerte7, NULL };
struct Border TaBorder6 =
{ 415, 31, 1, 0, JAM1, 3, TaWerte6, NULL };
struct Border TaBorder5 =
{ 415, 31, 2, 0, JAM1, 3, TaWerte5, &TaBorder6 };
struct Border TaBorder4 =
{ 0, 0, 1, 0, JAM1, 3, TaWerte4, NULL };
struct Border TaBorder3 =
{ 0, 0, 2, 0, JAM1, 3, TaWerte3, &TaBorder4 };
struct Border TaBorder2 =
{ 6, 22, 2, 0, JAM1, 3, TaWerte2, &TaBorder5 };
struct Border TaBorder1 =
{ 6, 22, 1, 0, JAM1, 3, TaWerte1, &TaBorder2 };
struct PropInfo TaProp1 =
{ AUTOKNOB | FREEVERT | PROPBORDERLESS, 1, 1, 0x100, 0x100,
  0, 0, 0, 0, 0, 0 };
struct Gadget TaGadget3 =
{ NULL, 416, 32, 19, 105, GADGHCOMP, GADGIMMEDIATE | RELVERIFY, PROPGADGET,
  &TaImage1, NULL, NULL, NULL, &TaProp1, 3, NULL };
struct Gadget TaGadget2 =
{ &TaGadget3, 415, 138, 21, 9, GADGHCOMP, GADGIMMEDIATE | RELVERIFY, BOOLGADGET,
  &TaBorder8, NULL, NULL, NULL, NULL, 2, NULL };
struct Gadget TaGadget1 =
{ &TaGadget2, 415, 22, 21, 9, GADGHCOMP, GADGIMMEDIATE | RELVERIFY, BOOLGADGET,
  &TaBorder7, NULL, NULL, NULL, NULL, 1, NULL };
struct NewWindow TableNewWindow =
{ 95, 50, 441, 150, -1, -1, CLOSEWINDOW | GADGETUP | GADGETDOWN,
  WINDOWDEPTH | WINDOWDRAG | WINDOWCLOSE | SMART_REFRESH | ACTIVATE,
  &TaGadget1, NULL, (UBYTE *)"Tabellarische Übersicht",
  NULL, NULL, 116, 50, 408, 140, WBENCHSCREEN };

/*********************************************
 * globale Strukturen für Informationswindow *
 *********************************************/

char ueberschrift[] = "           CrossAss Version 1.0";
SHORT InfoWerte1[] =
{ 6, 52, 6, 15, 353, 15 };
SHORT InfoWerte2[] =
{ 353, 16, 353, 52, 7, 52 };
SHORT InfoWerte3[] =
{ 60, 85, 60, 55, 292, 55 };
SHORT InfoWerte4[] =
{ 292, 56, 292, 85, 61, 85 };
struct Border InfoBorder4 =
{ 0, 0, 2, 0, JAM1, 3, InfoWerte4, NULL };
struct Border InfoBorder3 =
{ 0, 0, 1, 0, JAM1, 3, InfoWerte3, &InfoBorder4 };
struct Border InfoBorder2 =
{ 0, 0, 1, 0, JAM1, 3, InfoWerte2, &InfoBorder3 };
struct Border InfoBorder1 =
{ 0, 0, 2, 0, JAM1, 3, InfoWerte1, &InfoBorder2 };
struct IntuiText InfoText7 =
{ 1, 0, JAM2, 8, 74, &Font,
  (UBYTE *)"                                   ", NULL };
struct IntuiText InfoText6 =
{ 1, 0, JAM2, 8, 66, &Font,
  (UBYTE *)"                                   ", &InfoText7 };
struct IntuiText InfoText5 =
{ 1, 0, JAM2, 8, 58, &Font,
  (UBYTE *)"                                   ", &InfoText6 };
struct IntuiText InfoText4 =
{ 3, 0, JAM2, 31, 42, &Font,
  (UBYTE *)"(C)opyright 1994 MagnaMedia Verlag AG", &InfoText5 };
struct IntuiText InfoText3 =
{ 3, 0, JAM2, 11, 32, &Font,
  (UBYTE *)"    programmiert von Christian Krenner", &InfoText4 };
struct IntuiText InfoText2 =
{ 2, 0, JAM1, 11, 18, &Font,
  (UBYTE *)ueberschrift, &InfoText3 };
struct IntuiText InfoText1 =
{ 3, 0, JAM2, 13, 19, &Font,
  (UBYTE *)ueberschrift, &InfoText2 };
struct NewWindow InfoNewWindow =
{ 136, 55, 360, 90, -1, -1, CLOSEWINDOW,
  WINDOWDEPTH | WINDOWDRAG | WINDOWCLOSE | SMART_REFRESH | ACTIVATE,
  NULL, NULL, (UBYTE *)"Informationen",
  NULL, NULL, 116, 50, 408, 140, WBENCHSCREEN };

/*************************************************************
 * globale Strukturen für Dateinameneingabe (nur OS 1.2/1.3) *
 *************************************************************/

char dateistrbuffer[256];
char dateistrundo[256];
SHORT DateiWerte1[] =
{ 0, 9, 0, 0, 354, 0 };
SHORT DateiWerte2[] =
{ 354, 1, 354, 9, 1, 9 };
SHORT DateiWerte3[] =
{ 0, 11, 0, 0, 356, 0 };
SHORT DateiWerte4[] =
{ 356, 1, 356, 11, 1, 11 };
struct IntuiText DateiText1 =
{ 1, 0, JAM2, 16, 16, &Font, NULL, NULL };
struct Border DateiBorder4 =
{ -2, -2, 1, 0, JAM1, 3, DateiWerte4, NULL };
struct Border DateiBorder3 =
{ -2, -2, 2, 0, JAM1, 3, DateiWerte3, &DateiBorder4 };
struct Border DateiBorder2 =
{ -1, -1, 2, 0, JAM1, 3, DateiWerte2, &DateiBorder3 };
struct Border DateiBorder1 =
{ -1, -1, 1, 0, JAM1, 3, DateiWerte1, &DateiBorder2 };
struct StringInfo DateiStringInfo =
{ dateistrbuffer, dateistrundo, 0, 256, 0, 0, 0, 0, 0, 0, NULL, 0L, NULL };
struct Gadget DateiGadget1 =
{ NULL, 16, 29, 352, 8, GADGHCOMP, RELVERIFY, STRGADGET,
  &DateiBorder1, NULL, &DateiText1, NULL, &DateiStringInfo, 1, NULL };
struct NewWindow DateiNewWindow =
{ 128, 106, 384, 43, -1, -1, CLOSEWINDOW | GADGETUP,
  WINDOWDEPTH | WINDOWDRAG | WINDOWCLOSE | SMART_REFRESH | ACTIVATE,
  &DateiGadget1, NULL, (UBYTE *)"Dateinameneingabe",
  NULL, NULL, 116, 50, 408, 140, WBENCHSCREEN };

/*********************************************
 * globale Strukturen für Einstellungswindow *
 *********************************************/

char einst1strbuffer[10], einst2strbuffer[10], einst3strbuffer[10];
char einststrundo[10], einst4strbuffer[8];
SHORT EinstWerte1[] =
{ 0, 9, 0, 0, 170, 0 };
SHORT EinstWerte2[] =
{ 170, 1, 170, 9, 1, 9 };
SHORT EinstWerte3[] =
{ 0, 11, 0, 0, 172, 0 };
SHORT EinstWerte4[] =
{ 172, 1, 172, 11, 1, 11 };
SHORT EinstWerte5[] =
{ 0, 9, 0, 0, 98, 0 };
SHORT EinstWerte6[] =
{ 98, 1, 98, 9, 1, 9 };
SHORT EinstWerte7[] =
{ 0, 11, 0, 0, 100, 0 };
SHORT EinstWerte8[] =
{ 100, 1, 100, 11, 1, 11 };
SHORT EinstWerte9[] =
{ 0, 11, 0, 0, 48, 0 };
SHORT EinstWerte10[] =
{ 48, 1, 48, 11, 1, 11 };
struct StringInfo Einst4StringInfo =
{ einst4strbuffer, einststrundo, 0, 7, 0, 0, 0, 0, 0, 0, NULL, 0L, NULL };
struct StringInfo Einst3StringInfo =
{ einst3strbuffer, einststrundo, 0, 9, 0, 0, 0, 0, 0, 0, NULL, 0L, NULL };
struct StringInfo Einst2StringInfo =
{ einst2strbuffer, einststrundo, 0, 9, 0, 0, 0, 0, 0, 0, NULL, 0L, NULL };
struct StringInfo Einst1StringInfo =
{ einst1strbuffer, einststrundo, 0, 9, 0, 0, 0, 0, 0, 0, NULL, 0L, NULL };
struct Border EinstBorder10 =
{ 0, 0, 1, 0, JAM1, 3, EinstWerte10, NULL };
struct Border EinstBorder9 =
{ 0, 0, 2, 0, JAM1, 3, EinstWerte9, &EinstBorder10 };
struct Border EinstBorder8 =
{ -2, -2, 1, 0, JAM1, 3, EinstWerte8, NULL };
struct Border EinstBorder7 =
{ -2, -2, 2, 0, JAM1, 3, EinstWerte7, &EinstBorder8 };
struct Border EinstBorder6 =
{ -1, -1, 2, 0, JAM1, 3, EinstWerte6, &EinstBorder7 };
struct Border EinstBorder5 =
{ -1, -1, 1, 0, JAM1, 3, EinstWerte5, &EinstBorder6 };
struct Border EinstBorder4 =
{ -2, -2, 1, 0, JAM1, 3, EinstWerte4, NULL };
struct Border EinstBorder3 =
{ -2, -2, 2, 0, JAM1, 3, EinstWerte3, &EinstBorder4 };
struct Border EinstBorder2 =
{ -1, -1, 2, 0, JAM1, 3, EinstWerte2, &EinstBorder3 };
struct Border EinstBorder1 =
{ -1, -1, 1, 0, JAM1, 3, EinstWerte1, &EinstBorder2 };
struct IntuiText EinstText5 =
{ 1, 0, JAM2, 186, 51, &Font, (UBYTE *)"                ", NULL };
struct IntuiText EinstText4 =
{ 1, 0, JAM2, 186, 28, &Font, (UBYTE *)"                ", &EinstText5 };
struct IntuiText EinstText1 =
{ 1, 0, JAM2, 2, -10, &Font, (UBYTE *)"Einträge Labeltabelle", NULL };
struct IntuiText EinstText2 =
{ 1, 0, JAM2, 2, -10, &Font, (UBYTE *)"Einträge Makrotabelle", NULL };
struct IntuiText EinstText3 =
{ 1, 0, JAM2, 2, -10, &Font, (UBYTE *)"Größe Makrospeicher", NULL };
struct IntuiText EinstText7 =
{ 1, 0, JAM2, 2, -10, &Font, (UBYTE *)"Refresh-Rate", NULL };
struct IntuiText EinstText8 =
{ 1, 0, JAM2, 70, 2, &Font, (UBYTE *)"OK !", NULL };
struct IntuiText EinstText9 =
{ 1, 0, JAM2, 8, 2, &Font, (UBYTE *)"Sort", NULL };
struct Gadget EinstGadget6 =
{ NULL, 238, 90, 49, 12, GADGHCOMP, RELVERIFY | TOGGLESELECT, BOOLGADGET,
  &EinstBorder9, NULL, &EinstText9, NULL, NULL, 6, NULL };
struct Gadget EinstGadget5 =
{ &EinstGadget6, 14, 90, 181, 12, GADGHCOMP, RELVERIFY, BOOLGADGET,
  &GadgetBorder1, NULL, &EinstText8, NULL, NULL, 5, NULL };
struct Gadget EinstGadget4 =
{ &EinstGadget5, 212, 74, 96, 8, GADGHCOMP, RELVERIFY | STRINGCENTER |
  LONGINT, STRGADGET, &EinstBorder5, NULL, &EinstText7, NULL,
  &Einst4StringInfo, 4, NULL };
struct Gadget EinstGadget3 =
{ &EinstGadget4, 14, 74, 168, 8, GADGHCOMP, RELVERIFY | STRINGCENTER |
  LONGINT, STRGADGET, &EinstBorder1, NULL, &EinstText3, NULL,
  &Einst3StringInfo, 3, NULL };
struct Gadget EinstGadget2 =
{ &EinstGadget3, 14, 51, 168, 8, GADGHCOMP, RELVERIFY | STRINGCENTER |
  LONGINT, STRGADGET, &EinstBorder1, NULL, &EinstText2, NULL,
  &Einst2StringInfo, 2, NULL };
struct Gadget EinstGadget1 =
{ &EinstGadget2, 14, 28, 168, 8, GADGHCOMP, RELVERIFY | STRINGCENTER |
  LONGINT, STRGADGET, &EinstBorder1, NULL, &EinstText1, NULL,
  &Einst1StringInfo, 1, NULL };
struct NewWindow EinstNewWindow =
{ 154, 50, 332, 106, -1, -1, CLOSEWINDOW | GADGETUP,
  WINDOWDEPTH | WINDOWDRAG | WINDOWCLOSE | SMART_REFRESH | ACTIVATE,
  &EinstGadget1, NULL, (UBYTE *)"Einstellungen",
  NULL, NULL, 116, 50, 408, 140, WBENCHSCREEN };

/**************************************************
 * globale Variablen, Zeiger, Arrays und Tabellen *
 **************************************************/

VOID *AllocMem();
void *OpenLibrary();
struct Window *OpenWindow();
unsigned long AvailMem();

struct Einstellungen Einst =
{ 32768L, 128L*(long)sizeof(struct Macro),
  2000L*(long)sizeof(struct Label),20,TRUE };
extern struct ExecBase *SysBase;
BOOL   OS20;
BOOL DateiReq(char *filename,char *AnzeigeText,char *Show);
extern int Enable_Abort;
struct IntuitionBase *IntuitionBase = 0L;
struct Window *MainWindow = 0L;
struct MacroStack MacroStack[32];
struct MacroStack *MacroPointer;
struct Macro *MacroTable = 0L;
char *MacroMem = 0L;
struct Block BlockTable[32];
char blockcounter = 0;
struct IncludeStack IncludeStack[32];
struct IncludeStack *IncludePointer;
struct Label *LabelTable = 0L;
char workbuffer[256];
char *actposition = 0L;
unsigned char mainbuffer[512];
unsigned char outbuffer[512];
unsigned int pos = 0;
unsigned long bufferlenght = 512L;
unsigned long actlenght = 512L;
unsigned long endbuffer = 0L;
unsigned int macronumber = 0, actmacro = 0;
char *macroup = 0L;
unsigned long labelnumber = 0L;
struct FileHandle *SourceHandle = 0L;
struct FileHandle *ObjectHandle = 0L;
struct FileHandle *PrintHandle = 0L;
/* struct FileHandle *Open(); */
char mnemonic, pseudo, macro;
char test[256], operand[32][80];
unsigned int pc = 0, params[10], start, over, aver;
BOOL defd[10], run;
unsigned char error = 255;
char pass = 0;
unsigned long completelines = 0L, lines = 0L;
char actname[256], objname[256], srcname[256], prtname[256];
BOOL nerror = FALSE;
char *zeiger, label[32], paramcount;
unsigned int linelenght = 0;
BOOL define = TRUE, prtflag = FALSE, printed = FALSE;
unsigned char zeile[256];
unsigned int aufruf;

#define MNEMONICS 56
char mnemonics[MNEMONICS][4] =
{
   "LDA", "LDX", "LDY", "STA", "STX", "STY",
   "TAX", "TAY", "TXA", "TYA", "TXS", "TSX",
   "PLA", "PHA", "PLP", "PHP", "ADC", "SBC",
   "INC", "DEC", "INX", "DEX", "INY", "DEY",
   "AND", "ORA", "EOR", "CMP", "CPX", "CPY",
   "BIT", "BCC", "BCS", "BEQ", "BNE", "BMI",
   "BPL", "BVC", "BVS", "JMP", "JSR", "ASL",
   "LSR", "ROL", "ROR", "CLC", "CLD", "CLI",
   "CLV", "SEC", "SED", "SEI", "NOP", "RTS",
   "RTI", "BRK"
};

#define PSEUDOS 13
char pseudos[PSEUDOS][11] =
{
   "BYTE", "WORD", "EQUAL", "BASE", "INCLUDE",
   "IF", "ELSE", "ENDIF", "APPEND", "MACRO",
   "ENDMACRO", "BLOCK", "ASCII"
};

unsigned char opcodes[MNEMONICS][12] =
{
   { 0xa9,0xad,0xbd,0xb9,0xa5,0xb5,0xff,0xa1,0xb1,0xff,0xff,0xff },
   { 0xa2,0xae,0xff,0xbe,0xa6,0xff,0xb6,0xff,0xff,0xff,0xff,0xff },
   { 0xa0,0xac,0xbc,0xff,0xa4,0xb4,0xff,0xff,0xff,0xff,0xff,0xff },
   { 0xff,0x8d,0x9d,0x99,0x85,0x95,0xff,0x81,0x91,0xff,0xff,0xff },
   { 0xff,0x8e,0xff,0xff,0x86,0xff,0x96,0xff,0xff,0xff,0xff,0xff },
   { 0xff,0x8c,0xff,0xff,0x84,0x94,0xff,0xff,0xff,0xff,0xff,0xff },
   { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xaa },
   { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xa8 },
   { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x8a },
   { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x98 },
   { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x9a },
   { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xba },
   { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x68 },
   { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x48 },
   { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x28 },
   { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x08 },
   { 0x69,0x6d,0x7d,0x79,0x65,0x75,0xff,0x61,0x71,0xff,0xff,0xff },
   { 0xe9,0xed,0xfd,0xf9,0xe5,0xf5,0xff,0xe1,0xf1,0xff,0xff,0xff },
   { 0xff,0xee,0xfe,0xff,0xe6,0xf6,0xff,0xff,0xff,0xff,0xff,0xff },
   { 0xff,0xce,0xde,0xff,0xc6,0xd6,0xff,0xff,0xff,0xff,0xff,0xff },
   { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe8 },
   { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xca },
   { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xc8 },
   { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x88 },
   { 0x29,0x2d,0x3d,0x39,0x25,0x35,0xff,0x21,0x31,0xff,0xff,0xff },
   { 0x09,0x0d,0x1d,0x19,0x05,0x15,0xff,0x01,0x11,0xff,0xff,0xff },
   { 0x49,0x4d,0x5d,0x59,0x45,0x55,0xff,0x41,0x51,0xff,0xff,0xff },
   { 0xc9,0xcd,0xdd,0xd9,0xc5,0xd5,0xff,0xc1,0xd1,0xff,0xff,0xff },
   { 0xe0,0xec,0xff,0xff,0xe4,0xff,0xff,0xff,0xff,0xff,0xff,0xff },
   { 0xc0,0xcc,0xff,0xff,0xc4,0xff,0xff,0xff,0xff,0xff,0xff,0xff },
   { 0xff,0x2c,0xff,0xff,0x24,0xff,0xff,0xff,0xff,0xff,0xff,0xff },
   { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x90,0xff,0xff },
   { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xb0,0xff,0xff },
   { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0xff,0xff },
   { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xd0,0xff,0xff },
   { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x30,0xff,0xff },
   { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x10,0xff,0xff },
   { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x50,0xff,0xff },
   { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x70,0xff,0xff },
   { 0xff,0x4c,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x6c,0xff },
   { 0xff,0x20,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff },
   { 0xff,0x0e,0x1e,0xff,0x06,0x16,0xff,0xff,0xff,0xff,0xff,0x0a },
   { 0xff,0x4e,0x5e,0xff,0x46,0x56,0xff,0xff,0xff,0xff,0xff,0x4a },
   { 0xff,0x2e,0x3e,0xff,0x26,0x36,0xff,0xff,0xff,0xff,0xff,0x2a },
   { 0xff,0x6e,0x7e,0xff,0x66,0x76,0xff,0xff,0xff,0xff,0xff,0x6a },
   { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x18 },
   { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xd8 },
   { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x58 },
   { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xb8 },
   { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x38 },
   { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf8 },
   { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x78 },
   { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xea },
   { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x60 },
   { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x40 },
   { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00 },
};

char laenge[12] =
{
   2, 3, 3, 3, 2, 2, 2, 2, 2, 2, 3, 1
};

#define ERRORS 66
char errors[ERRORS][47] =
{
   "Fehler beim Lesen der Quelldatei !           ",    /* 0 */
   "Fehler beim Öffnen der Quell-/Include-Datei !",    /* 1 */
   "Quellcodezeile zu lang (max. 255 Zeichen) !  ",    /* 2 */
   "Label bereits definiert !                    ",    /* 3 */
   "Zu viele Operanden (max. 32) !               ",    /* 4 */
   "Fehlerhafter Label-/Mnemonic-/Makro-Name !   ",    /* 5 */
   "Labeltabelle voll !                          ",    /* 6 */
   "Operand zu lang (max. 128 Zeichen) !         ",    /* 7 */
   "Zu viele Includefiles (max. 32) !            ",    /* 8 */
   "Includefilename fehlt !                      ",    /* 9 */
   "Makroname fehlt !                            ",    /* 10 */
   "Makrotabelle voll !                          ",    /* 11 */
   "Makrospeicher voll !                         ",    /* 12 */
   ".ENDMACRO fehlt !                            ",    /* 13 */
   "Keine Schachtelung von Makrodefinitionen !   ",    /* 14 */
   "Zu viele Makros (max. 32) !                  ",    /* 15 */
   "Unbekannte Rechenoperation !                 ",    /* 16 */
   "Unerlaubte Ziffer !                          ",    /* 17 */
   "Überlauf (Ergebnis > 65535) !                ",    /* 18 */
   "Kein .INCLUDE innerhalb Makrodefinition !    ",    /* 19 */
   "Mnemonic/Pseudoopcode/Makro erwartet !       ",    /* 20 */
   "Labelname zu lang (max. 32 Zeichen) !        ",    /* 21 */
   "Zuzuweisender Wert fehlt !                   ",    /* 22 */
   "Labelname fehlt !                            ",    /* 23 */
   "Unbekanntes Label !                          ",    /* 24 */
   "Makroparameter fehlt !                       ",    /* 25 */
   "Unbekannter Makroparameter !                 ",    /* 26 */
   "Makroparameternummer erwartet !              ",    /* 27 */
   "Term unvollständig !                         ",    /* 28 */
   "Unbekannte Adressierungsart !                ",    /* 29 */
   "Operand zu lang, Byte erwartet !             ",    /* 30 */
   "Unerlaubte Adressierungsart !                ",    /* 31 */
   "Startadresse fehlt !                         ",    /* 32 */
   "Branchsprung außerhalb Reichweite !          ",    /* 33 */
   "Fehler beim Öffnen der Objektdatei !         ",    /* 34 */
   "Fehler beim Schreiben in Objektdatei !       ",    /* 35 */
   "Zu wenig Speicher frei !                     ",    /* 36 */
   "Assemblierung abgebrochen !                  ",    /* 37 */
   ".ENDMACRO ohne .MACRO !                      ",    /* 38 */
   "Filename der Objektdatei fehlt !             ",    /* 39 */
   ".BASE-Befehl mit Objektdateiname fehlt !     ",    /* 40 */
   "Vergleichsoperand fehlt !                    ",    /* 41 */
   "Zu viele Makroparameter (max. 10) !          ",    /* 42 */
   "Kann Window nicht öffnen !                   ",    /* 43 */
   "Fehler beim Abspeichern der Einstellungen !  ",    /* 44 */
   "Fehler beim Laden der Einstellungen !        ",    /* 45 */
   "Fehler beim Öffnen des Parallelports !       ",    /* 46 */
   "Fehler beim Lesen der Objektdatei !          ",    /* 47 */
   "Fehler beim Senden über Parallelport !       ",    /* 48 */
   "Übertragung läuft...                         ",    /* 49 */
   "ASCII-Zeichen erwartet !                     ",    /* 50 */
   "Fehler in Konvertierungstabellendatei !      ",    /* 51 */
   "Lade Konvertierungstabelle...                ",    /* 52 */
   "Lade Einstellungsdatei...                    ",    /* 53 */
   "Speichere Einstellungsdatei...               ",    /* 54 */
   "Unerlaubte Labelposition !                   ",    /* 55 */
   "Sortiere Labeltabelle...                     ",    /* 56 */
   "Quelldateiausdruck angeschaltet...           ",    /* 57 */
   "Quelldateiausdruck ausgeschaltet...          ",    /* 58 */
   "Fehler beim Öffnen der Druckdatei !          ",    /* 59 */
   "Fehler beim Ausdruck !                       ",    /* 60 */
   "Druck läuft...                               ",    /* 61 */
   "Vergleichoperator fehlt !                    ",    /* 62 */
   "Unbekannter/Unerlaubter Vergleichsoperator ! ",    /* 63 */
   "Division durch 0 !                           ",    /* 64 */
   "Makro bereits definiert !                    "     /* 65 */
};

unsigned char addr[5][5] =
{
   { '(',',','x',')', 7 },
   { '(',')',',','y', 8 },
   { 255,255,',','x', 5 },
   { 255,255,',','y', 6 },
   { '(',255,255,')', 10 }
};

/********************
 * Programm beenden *
 ********************/

void freeit()
{
   if(LabelTable)
      FreeMem(LabelTable, Einst.labellenght);
   if(MacroMem)
      FreeMem(MacroMem, Einst.macromemlenght);
   if(MacroTable)
      FreeMem(MacroTable, Einst.macrotablelenght);
   if(SourceHandle)
      Close(SourceHandle);
   LabelTable = MacroMem = MacroTable = SourceHandle = 0L;
}

/***********************************
 * Alles öffnen und initialisieren *
 ***********************************/

BOOL init()
{
   workbuffer[0] = '\0';

   if(!(MacroTable = (struct Macro *)
      AllocMem(Einst.macrotablelenght, MEMF_CLEAR)))
   {
      error = 36;
      return(FALSE);
   }
   if(!(MacroMem = (char *)
      AllocMem(Einst.macromemlenght, MEMF_CLEAR)))
   {
      error = 36;
      return(FALSE);
   }
   if(!(LabelTable = (struct Label *)
      AllocMem(Einst.labellenght, MEMF_CLEAR)))
   {
      error = 36;
      return(FALSE);
   }
   return(TRUE);
}

/*************************
 * Hauptwindow schließen *
 *************************/

void closeall()
{
   if(MainWindow)
   {
      ClearMenuStrip(MainWindow);
      CloseWindow(MainWindow);
   }
   if(IntuitionBase)
      CloseLibrary(IntuitionBase);
   exit(FALSE);
}

/**********************
 * Hauptwindow öffnen *
 **********************/
extern BOOL saveeinst();
extern BOOL loadeinst();

void openall()
{
   register int i;

   OS20 = (SysBase->LibNode.lib_Version >= 37);

   if(!(IntuitionBase = (struct IntuitionBase *)
      OpenLibrary("intuition.library", 0L)))
      closeall();
   Gadget1.GadgetText = &GadgetText1;
   for(i=0; i<256; i++)
      Einst.converttable[i] = i;
   if(!(MainWindow = (struct Window *)
      OpenWindow(&MainNewWindow)))
      closeall();
   if(!loadeinst())
   {
      error = 255;
      saveeinst();
   }
   SetMenuStrip(MainWindow, &MenuDatei);
   DrawBorder(MainWindow->RPort, &Border1, 0L, 0L);
   prtname[0] = '\0';
}

/*****************************
 * Datei zum Anhängen öffnen *
 *****************************/

struct FileHandle *append(name)
char *name;
{
   struct FileHandle *handle = 0L;

   if(handle = Open(name, MODE_OLDFILE))
   {
      if(Seek(handle, 0L, 1L) == 1L)
      {
         Close(handle);
         return((struct FileHandle *)0L);
      }
   }
   else
   {
      if(!(handle = Open(name, MODE_NEWFILE)))
         return((struct FileHandle *)0L);
   }
   return(handle);
}

/***********************
 * Status neu anzeigen *
 ***********************/

void refreshstatus()
{
   if((actmacro == macronumber) || !macronumber)
   {
      if(actname[0])
         sprintf(Text2.IText, "Quelldatei:  %-32.32s", actname);
      else
         sprintf(Text2.IText, "Quelldatei:  --------------------------------");
   }
   else
      sprintf(Text2.IText, "akt. Makro:  %-32.32s", MacroTable[actmacro].name);
   if(objname[0])
      sprintf(Text3.IText, "Objektdatei: %-32.32s", objname);
   else
      sprintf(Text3.IText, "Objektdatei: --------------------------------");
   sprintf(Text4.IText, "Code: $%04x - $%04x     Länge: %05u Byte", 
            start, pc, pc-start);
   sprintf(Text5.IText, "Anzahl Symbole: %05lu   Anzahl Makros: %05u",
            labelnumber, macronumber);
   sprintf(Text6.IText, "Zeile: %06lu  Zeilen insg: %06lu   Pass: -",
            lines, completelines);
   if(error == 255)
   {
      if(run)
         sprintf(Text7.IText, "Assemblierung läuft...                       ");
      else
         sprintf(Text7.IText, "Kein Fehler aufgetreten.                     ");
   }
   else
      sprintf(Text7.IText, "%s", errors[error]);
   if(pass)
      Text6.IText[43] = pass+'0';
   else
      Text6.IText[43] = '-';
   PrintIText(MainWindow->RPort, &Text1, 0L, 0L);
}

/***************************************************
 * Ausgabe einer unbearbeiteten Zeile für Ausdruck *
 ***************************************************/

BOOL printline()
{
   char pstring[320];

   if(prtflag && (pass == 2))
   {
      printed = TRUE;
      sprintf(pstring, "%7lu : %04x          %s\n", completelines, pc, workbuffer);
      if((Write(PrintHandle, pstring, (long)strlen(pstring))) !=
      (long)strlen(pstring))
      {
         error = 60;
         return(FALSE);
      }
   }
   return(TRUE);
}

/*********************************
 * Filenamenausgabe für Ausdruck *
 *********************************/

BOOL printnames()
{
   char text[640];

   if(prtflag && (pass == 2))
   {
      sprintf(text, "\nQuelldatei: %s\nObjektdatei: %s\n\n", actname, objname);
      if((Write(PrintHandle, text, (long)strlen(text))) !=
         (long)strlen(text))
      {
         error = 60;
         return(FALSE);
      }
   }
   return(TRUE);
}

/******************
 * Zahl ermitteln *
 ******************/

unsigned int getstatement();
unsigned long searchlabel();

unsigned long getnumber()
{
   char low = 0;
   register char pot = 10;
   register unsigned long result = 0L;
   char label[32], i;

   nerror = FALSE;

   if(!*zeiger)
   {
      nerror = TRUE;
      error = 28;
      return(0);
   }
   if(*zeiger == '<') /* Vorzeichen */
   {      
      zeiger++;
      low = 1;
   }
   if(*zeiger == '>')
   {
      zeiger++;
      low = 2;
   }

   if((*zeiger == '(') || (*zeiger == '[')) /* Terme */
   {
      zeiger++;
      result = (unsigned long)getstatement();
      if(nerror)
         return(0);
      goto einsprung; /* Unsauber aber wirkungsvoll */
   }

   if(*zeiger == '*') /* Programmcounter */
   {
      zeiger++;
      result = (unsigned long)pc;
      goto einsprung; /* siehe oben */
   }

   if(*zeiger == '?') /* Makroparameter */
   {
      zeiger++;
      if((!*zeiger) || (!isdigit(*zeiger)))
      {
         nerror = TRUE;
         error = 27;
         return(0);
      }
      i = *zeiger - '0';
      zeiger++;
      if(i >= paramcount)
      {
         nerror = TRUE;
         error = 26;
         return(0);
      }
      if(!defd[i])
      {
         error = 24;
         nerror = TRUE;
         return(0);
      }
      result = (unsigned long)params[i];
      goto einsprung; /* siehe oben */
   }

   if(*zeiger == '\'') /* ASCII-Wert (konvertiert) */
   {
      zeiger++;
      if(!*zeiger)
      {
         nerror = TRUE;
         error = 50;
         return(0);
      }
      result = (long)(Einst.converttable[*zeiger]);
      zeiger++;
      goto einsprung;
   }

   if(isalpha(*zeiger)) /* Labelwerte */
   {
      i = 0;
      do
      {
         label[i] = *zeiger;
         i++;
         zeiger++;
      } while((i<32) && (isdigit(*zeiger) || isalpha(*zeiger) ||
                         (*zeiger == '_')));
      if(i==32)
      {
         error = 21;
         nerror = TRUE;
         return(0);
      }
      label[i] = 0;
      if((result = searchlabel(label)) == labelnumber)
      {
         error = 24;
         nerror = TRUE;
         return(0);
      }
      result = (unsigned long)LabelTable[result].wert;
      goto einsprung; /* siehe oben */
   }

   switch(*zeiger) /* Hex-, Dez-, Binär und Oktalzahlen */
   {
      case '$':
         pot = 16;
         zeiger++;
         break;
      case '%':
         pot = 2;
         zeiger++;
         break;
      case '&':
         pot = 8;
         zeiger++;
         break;
   }

   do
   {
      if(isalpha(*zeiger))
      {
         if((pot != 16) || (toupper(*zeiger) > 'F'))
         {
            error = 17;
            nerror = TRUE;
            return(0);
         }
         result = result * 16L + (long)(toupper(*zeiger) - 'A' + 10);
      }
      if(isdigit(*zeiger))
      {
         if((*zeiger-'0') >= pot)
         {
            error = 17;
            nerror = TRUE;
            return(0);
         }
         result = result * (long)pot + (long)(toupper(*zeiger) - '0');
      }
      zeiger++;
   } while(isdigit(*zeiger) || isalpha(*zeiger));

   einsprung:
   if(result > 65535)
   {
      error = 18;
      nerror = TRUE;
      return(0);
   }
   if(low == 1)
      return(result - 256L * (result / 256L));
   if(low == 2)
      return(result / 256L);
   return(result);
}

/******************
 * Term berechnen *
 ******************/

unsigned int getstatement()
{
   register unsigned long result = 0L, zresult;
   char rechenz = '+', nrechenz = '*';
   unsigned long w;

   while(*zeiger && (rechenz != ')') && (rechenz != ']'))
   {
      zresult = 1L;
      nrechenz = '*';
      do
      {
         switch(nrechenz)
         {
            case '*':
               zresult *= getnumber();
               break;
            case '/':
               if(!(w = getnumber()))
               {
                  nerror = TRUE;
                  error = 64;
                  return(0);
               }
               zresult /= w;
               break;
         }
         if(nerror)
            return(0);
         nrechenz = *zeiger;
         if(*zeiger)
            zeiger++;
      } while((nrechenz == '*') || (nrechenz == '/'));
      if(nrechenz)
         zeiger--;

      switch(rechenz)
      {
         case '+':
            result += zresult;
            break;
         case '-':
            result -= zresult;
            break;
         case '|':
            result |= zresult;
            break;
         case '&':
            result &= zresult;
            break;
         case '<':
            result <<= zresult;
            break;
         case '>':
            result >>= zresult;
            break;
         default:
            error = 16;
            nerror = TRUE;
            return(0);
      }
      rechenz = *zeiger;
      if(rechenz)
         zeiger++;
   }
   if(result > 65535L)
   {
      error = 18;
      nerror = TRUE;
      return(0);
   }
   nerror = FALSE;
   return((unsigned int)result);
}

/***********************
 * Buffer neu einlesen *
 ***********************/

BOOL readbuffer()
{
   actlenght = Read(SourceHandle, mainbuffer, bufferlenght);
   if(IoErr() >= 100)
      return(FALSE);
   endbuffer = mainbuffer+actlenght;
   actposition = mainbuffer;
   return(TRUE);
}

/**************************
 * Zeile aus Buffer holen *
 **************************/

BOOL getline()
{
   register char counter = 0;
   char i;

   while(((*actposition != 0x0a) && (counter < 255)) ||
         (actposition == (char *)endbuffer))
   {
      if(actposition == (char *)endbuffer)
      {
         if(actlenght == bufferlenght)
         {
            if(!readbuffer())
               return(FALSE);
            continue;
         }
         else
         {
            if(MacroPointer == MacroStack)
            {
               actmacro = macronumber;
               if(SourceHandle)
                  Close(SourceHandle);
               SourceHandle = 0L;
               if(IncludePointer == IncludeStack)
                  return(FALSE);
               IncludePointer--;
               strcpy(actname, IncludePointer->lastfile);
               if(!(SourceHandle = (struct FileHandle *)
                  Open(actname, (ULONG)MODE_OLDFILE)))
               {
                  error = 1;
                  return(FALSE);
               }
               lines = 0L;
               if(!readbuffer())
                  return(FALSE);
               while(lines < (IncludePointer->lineafter))
               {
                  if(!getline())
                     return(FALSE);
                  completelines--;
               }
               if(!printnames())
                  return(FALSE);
               continue;
            }
            else
            {
               MacroPointer--;
               actposition = MacroPointer->pointer;
               endbuffer = MacroPointer->endbuffer;
               actlenght = MacroPointer->actlenght;
               actmacro = MacroPointer->number;
               lines = MacroPointer->lineafter;
               paramcount = MacroPointer->paramcount;
               aufruf = MacroPointer->aufruf;
               for(i=0; i<paramcount; i++)
               {
                  params[i] = MacroPointer->params[i];
                  defd[i] = MacroPointer->defd[i];
               }
               continue;
            }
         }
      }
      workbuffer[counter] = *actposition;
      counter++;
      actposition++;
   }
   if(counter == 255)
   {
      error = 2;
      return(FALSE);
   }
   workbuffer[counter] = 0;
   completelines++;
   lines++;
   actposition++;
   return(TRUE);
}

/****************
 * Label suchen *
 ****************/

unsigned long searchlabel(name)
char *name;
{
   register unsigned long number = 0L;

   while(number < labelnumber)
   {
      if(!strcmp(LabelTable[number].name, name))
      {
         if(LabelTable[number].aufruf == 0)
            return(number);
         if((LabelTable[number].macro == actmacro) &&
            (LabelTable[number].aufruf == aufruf))
            return(number);
      }
      number++;
   }
   return(labelnumber);
}

/*******************
 * Mnemonic suchen *
 *******************/

char searchmnemonic(source)
char *source;
{
   register char number = 0, i = 0;

   while(number < MNEMONICS)
   {
      for(i=0;(i<4) && (toupper(source[i]) == mnemonics[number][i]);i++)
         ;
      if(i==4)
         return(number);
      number++;
   }
   return(MNEMONICS);
}

/***********************
 * Pseudoopcode suchen *
 ***********************/

char searchpseudo(source)
char *source;
{
   register char number = 0, i = 0;

   if(source[0] != '.')
      return(PSEUDOS);
   while(number < PSEUDOS)
   {
      i=1;
      while((source[i]) && (toupper(source[i]) == pseudos[number][i-1]) &&
            (i<11))
         i++;
      if(i==11)
         break;
      if(!source[i])
         return(number);
      number++;
   }
   return(PSEUDOS);
}

/****************
 * Makro suchen *
 ****************/

unsigned int searchmacro(source)
char *source;
{
   register char i = 0;
   register unsigned int number = 0;

   while(number < macronumber)
   {
      i=0;
      while((source[i]) && (MacroTable[number].name[i]) &&
            (source[i] == MacroTable[number].name[i]))
         i++;
      if((!source[i]) && (!MacroTable[number].name[i]))
         return(number);
      number++;
   }
   return(macronumber);
}

/**************************
 * Neues Label definieren *
 **************************/

BOOL definelabel(name, number)
char *name;
unsigned int number;
{
   if(searchlabel(name) != labelnumber)
   {
      error = 3;
      return(FALSE);
   }
   if(((labelnumber+1L) * sizeof(struct Label)) >= Einst.labellenght)
   {
      error = 6;
      return(FALSE);
   }
   strcpy(LabelTable[labelnumber].name, name);
   LabelTable[labelnumber].wert = number;
   if(actmacro != macronumber)
   {
      LabelTable[labelnumber].aufruf = aufruf;
      LabelTable[labelnumber].macro = actmacro;
   }
   else
   {
      LabelTable[labelnumber].aufruf = 0;
      LabelTable[labelnumber].macro = 65535;
   }
   labelnumber++;
   return(TRUE);
}

/**********************************
 * Zeile in Bestandteile auflösen *
 **********************************/

BOOL divideline()
{
   register int i, u;
   register char *pointer = workbuffer;
   BOOL flag = TRUE;
   BOOL quote = FALSE;

   mnemonic = pseudo = macro = 0;
   test[0] = label[0] = '\0';
   for(i=0; i<32; i++)
      operand[i][0] = '\0';

   while(flag)
   {
      flag = FALSE;
      i=0;
      while((*pointer == ' ') || (*pointer == 0x09))
         pointer++;
      if(isdigit(*pointer))
      {
         error = 5;
         return(FALSE);
      }
      while((*pointer) && (*pointer != ';') && (*pointer != ' ') &&
            (*pointer != 0x09))
      {
         test[i] = *pointer;
         i++;
         pointer++;
      }
      test[i] = '\0';
      macro = macronumber;
      mnemonic = MNEMONICS;
      pseudo = PSEUDOS;
      if(!test[0] && !label[0])
         return(TRUE);
      if(!test[0] && label[0])
      {
         error = 20;
         return(FALSE);
      }
      if(((macro = searchmacro(test))==macronumber) &&
         ((mnemonic = searchmnemonic(test))==MNEMONICS) &&
         ((pseudo = searchpseudo(test))==PSEUDOS))
      {
         flag = TRUE;
         if(label[0])
         {
            error = 20;
            return(FALSE);
         }
         strcpy(label, test);
         if(strlen(label) >= 32)
         {
            error = 21;
            return(FALSE);
         }
      }
   }
   if(label[0] && (((pseudo >= 3) && (pseudo <= 8)) || (pseudo == 9) ||
                    (pseudo == 10)))
   {
      error = 55;
      return(FALSE);
   }
   if((pass == 1) && (pseudo != 2) && (label[0]) && define)
      if(!definelabel(label, pc))
         return(FALSE);

   i = u = 0;
   if(*pointer)
   {
      pointer++;
      while((*pointer) && (*pointer != ';'))
      {
         if(*pointer == '\"')
         {
            quote = (quote) ? FALSE : TRUE;
            pointer++;
            continue;
         }
         if((*pointer == ',') && (mnemonic == MNEMONICS) && (!quote))
         {
            operand[u][i] = '\0';
            pointer++;
            u++;
            i=0;
            if(u>31)
            {
               error = 4;
               return(FALSE);
            }
            continue;
         }
         if(((*pointer != ' ') && (*pointer != 0x09)) || (quote))
         {
            operand[u][i] = *pointer;
            i++;
            if(i == 80)
            {
               error = 7;
               return(FALSE);
            }
         }
         pointer++;
      }
      operand[u][i] = '\0';
   }
   return(TRUE);
}

/****************************************
 * Aktuellen Block in Tabelle eintragen *
 ****************************************/

void remarkblock()
{
   register int i;

   if((blockcounter < 32) && (objname[0]) && (pass == 1))
   {
      BlockTable[blockcounter].begin = start;
      BlockTable[blockcounter].end = pc;
      for(i=0;(i<31) && objname[i];i++)
         BlockTable[blockcounter].name[i] = objname[i];
      BlockTable[blockcounter].name[i] = '\0';
      blockcounter++;
   }
}

/*****************************
 * Pseudo-Opcodes bearbeiten *
 *****************************/

BOOL outbytes();

BOOL dopseudos()
{
   register unsigned char i;
   register unsigned int wert, anzahl;

   switch(pseudo)
   {
      case  0: /* .BYTE */
      {
         i = 0;
         while((operand[i][0]) && (i<32))
         {
            zeiger = operand[i];
            if(pass == 1)
               wert = 0;
            else
               wert = getstatement();
            if(nerror)
            {
               error = 255;
               wert = 0;
            }
            if(wert > 255)
            {
               error = 30;
               return(FALSE);
            }
            zeile[i] = (unsigned char)wert;
            i++;
         }
         linelenght = i;
         return(TRUE);
      }
      case  1: /* .WORD */
      {
         i = linelenght = 0;
         while((operand[i][0]) && (i<32))
         {
            zeiger = operand[i];
            if(pass == 1)
               wert = 1;
            else
               wert = getstatement();
            if(nerror)
            {
               error = 255;
               wert = 0;
            }
            zeile[linelenght] = (unsigned char)(wert - 256 * (wert / 256));
            zeile[linelenght+1] = (unsigned char)(wert / 256);
            linelenght += 2;
            i++;
         }
         return(TRUE);
      }
      case  2: /* .EQUAL */
      {
         if(pass == 2)
            return(TRUE);
         if(!operand[0][0])
         {
            error = 22;
            return(FALSE);
         }
         if(!label[0])
         {
            error = 23;
            return(FALSE);
         }
         zeiger = operand[0];
         wert = getstatement();
         if(nerror)
            return(FALSE);
         if(!definelabel(label, wert))
            return(FALSE);
         return(TRUE);
      }
      case  3: /* .BASE */
      {
         if(!operand[0][0])
         {
            error = 32;
            return(FALSE);
         }
         if(!operand[1][0])
         {
            error = 39;
            return(FALSE);
         }
         remarkblock();
         strcpy(objname, operand[1]);
         zeiger = operand[0];
         start = getstatement();
         if(nerror)
            return(FALSE);
         if(!printline())
            return(FALSE);
         if(!printnames())
            return(FALSE);
         pc = start;
         if(pass == 2)
         {
            if(ObjectHandle)
            {
               if(Write(ObjectHandle, outbuffer, (long)pos) != (long)pos)
               {
                  error = 36;
                  return(FALSE);
               }
               Close(ObjectHandle);
            }
            if(!(ObjectHandle = (struct FileHandle *)
               Open(objname, (ULONG)MODE_NEWFILE)))
            {
               error = 34;
               return(FALSE);
            }
            outbuffer[0] = (unsigned char)(start - 256 * (start / 256));
            outbuffer[1] = (unsigned char)(start / 256);
            pos = 2;
         }
         return(TRUE);
      }
      case  4: /* .INCLUDE */
      {
         if(!operand[0][0])
         {
            error = 9;
            return(FALSE);
         }
         if(IncludePointer == &IncludeStack[32])
         {
            error = 8;
            return(FALSE);
         }
         Close(SourceHandle);
         SourceHandle = 0L;
         strcpy(IncludePointer->lastfile, actname);
         IncludePointer->lineafter = lines;
         IncludePointer++;
         strcpy(actname, operand[0]);
         if(!(SourceHandle = (struct FileHandle *)
            Open(actname, (ULONG)MODE_OLDFILE)))
         {
            error = 1;
            return(FALSE);
         }
         lines = 0L;
         if(!readbuffer())
            return(FALSE);
         if(!printline())
            return(FALSE);
         if(!printnames())
            return(FALSE);
         return(TRUE);
      }
      case 5: /* .IF */
      case 6: /* .ELSE */
      {
         i = 0;
         if(pseudo == 5)
         {
            if(!operand[0][0])
            {
               error = 62;
               return(FALSE);
            }
            if(!operand[1][0])
            {
               error = 41;
               return(FALSE);
            }
            zeiger = operand[1];
            wert = getstatement();
            if(!operand[2][0])
            {
               switch(operand[0][0])
               {
                  case '=':
                     if(!nerror)
                        return(TRUE);
                     else
                     {
                        nerror = FALSE;
                        error = 255;
                     }
                     break;
                  case '!':
                     if(nerror)
                     {
                        nerror = FALSE;
                        error = 255;
                        return(TRUE);
                     }
                     break;
                  default:
                     error = 63;
                     return(FALSE);
               }
            }
            else
            {
               if(nerror)
                  return(FALSE);
               zeiger = operand[2];
               anzahl = getstatement();
               if(nerror)
                  return(FALSE);
               switch(operand[0][0])
               {
                  case  '=':
                     if(wert == anzahl)
                        return(TRUE);
                     break;
                  case  '!':
                     if(wert != anzahl)
                        return(TRUE);
                     break;
                  case  '<':
                     if(wert < anzahl)
                        return(TRUE);
                     break;
                  case  '>':
                     if(wert > anzahl)
                        return(TRUE);
                     break;
                  default:
                     error = 63;
                     return(FALSE);
               }
            }
            i = 1;
         }

         anzahl = pseudo = 0;
         define = FALSE;
         if(!printline())
            return(FALSE);
         do
         {
            if(pseudo == 5)
               anzahl++;
            if(pseudo == 7)
               anzahl--;
            if(!getline())
               return(FALSE);
            if(!divideline())
               return(FALSE);
            if(!printline())
               return(FALSE);
            if(pseudo == 8)
            {
               if(!dopseudos())
                  return(FALSE);
               continue;
            }
         } while(anzahl || ((i) ? ((pseudo != 6) && (pseudo != 7)) :
                                   (pseudo != 7)));
         define = TRUE;
         return(TRUE);
      }
      case 8: /* .APPEND */
      {
         Close(SourceHandle);
         SourceHandle = 0L;
         if(!operand[0][0])
         {
            error = 9;
            return(FALSE);
         }
         strcpy(actname, operand[0]);
         if(!(SourceHandle = (struct FileHandle *)
            Open(actname, (ULONG)MODE_OLDFILE)))
         {
            error = 1;
            return(FALSE);
         }
         lines = 0L;
         if(!readbuffer())
            return(FALSE);
         if(!printline())
            return(FALSE);
         if(!printnames())
            return(FALSE);
         return(TRUE);
      }
      case 9: /* .MACRO / .ENDMACRO */
      {
         if(pass != 1)
         {
            if(!printline())
               return(FALSE);
            printed = FALSE;
            while(pseudo != 10)
            {
               if(!getline())
               {
                  error = 13;
                  return(FALSE);
               }
               if(!divideline())
                  return(FALSE);
               if(pseudo == 8)
               {
                  if(!dopseudos())
                     return(FALSE);
                  continue;
               }
            }
            return(TRUE);
         }

         define = FALSE;
         if(!operand[0][0])
         {
            error = 10;
            return(FALSE);
         } 
         if(((macronumber+1) * sizeof(struct Macro)) > Einst.macrotablelenght)
         {
            error = 11;
            return(FALSE);
         }
         if(searchmacro(operand[0]) != macronumber)
         {
            error = 65;
            return(FALSE);
         }
         zeiger = operand[1];
         wert = getstatement();
         if(wert > 10)
         {
            error = 42;
            return(FALSE);
         }
         MacroTable[macronumber].paramcount = (char)wert;
         if(nerror)
            return(FALSE);
         MacroTable[macronumber].source = macroup;
         strcpy(MacroTable[macronumber].name, operand[0]);
         MacroTable[macronumber].aufruf = 0;
         i = 0;
         workbuffer[i] = 0;
         if(!printline())
            return(FALSE);
         printed = FALSE;
         while((macroup-MacroMem) < Einst.macromemlenght)
         {
            if(!workbuffer[i])
            {
               i = 0;
               if(!getline())
               {
                  error = 13;
                  return(FALSE);
               }
               if(!divideline())
                  return(FALSE);
               if(pseudo == 10)
                  break;
               if(pseudo == 9)
               {
                  error = 14;
                  return(FALSE);
               }
               if(pseudo == 4)
               {
                  error = 19;
                  return(FALSE);
               }
               if(pseudo == 8)
               {
                  if(!dopseudos())
                     return(FALSE);
                  continue;
               }
            }
            *macroup = workbuffer[i];
            macroup++;
            i++;
            if(!workbuffer[i])
            {
               *macroup = 0x0a;
               macroup++;
            }
         }
         if((macroup-MacroMem) == Einst.macromemlenght)
         {
            error = 12;
            return(FALSE);
         }
         MacroTable[macronumber].lenght = macroup -
                                          MacroTable[macronumber].source;
         macronumber++;
         actmacro = macronumber;
         define = TRUE;
         return(TRUE);
      }
      case 10: /* .ENDMACRO (ohne .MACRO !) */
      {
         error = 38;
         return(FALSE);
      }
      case 11: /* .BLOCK */
      {
         zeiger = operand[0];
         anzahl = getstatement();
         zeiger = operand[1];
         wert = getstatement();
         if(wert > 255)
         {
            error = 30;
            return(FALSE);
         }
         linelenght = 0;
         if(pass == 2)
         {
            while(anzahl > 3)
            {
               zeile[0] = (unsigned char)wert;
               linelenght = 1;
               if(!outbytes())
                  return(FALSE);
               pc++;
               anzahl--;
            }
            linelenght = anzahl;
            for(;anzahl > 0;anzahl--)
               zeile[anzahl-1] = (unsigned char)wert;
         }
         else
            pc += anzahl;
         return(TRUE);
      }
      case 12: /* .ASCII */
      {
         zeiger = operand[0];
         linelenght = 0;
         while(*zeiger)
         {
            zeile[linelenght] = Einst.converttable[*zeiger];
            linelenght++;
            zeiger++;
         }
         return(TRUE);
      }
   }
}

/*******************
 * Macro ausführen *
 *******************/

BOOL domacro()
{
   register char i;
   /* unsigned int wert; not used */
   struct MacroStack help;

   if(MacroPointer == &MacroStack[32])
   {
      error = 15;
      return(FALSE);
   }
   MacroPointer->pointer = actposition;
   for(i=0;i<10;i++)
   {
      MacroPointer->params[i] = params[i];
      MacroPointer->defd[i] = defd[i];
      help.params[i] = 0;
      help.defd[i] = FALSE;
   }
   MacroPointer->lineafter = lines;
   MacroPointer->endbuffer = (char *)endbuffer;
   MacroPointer->actlenght = actlenght;
   MacroPointer->paramcount = paramcount;
   MacroPointer->number = actmacro;
   MacroPointer->aufruf = aufruf;
   MacroPointer++;
   actposition = MacroTable[macro].source;
   actlenght = MacroTable[macro].lenght;
   endbuffer = actposition + actlenght;
   help.paramcount = MacroTable[macro].paramcount;
   MacroTable[macro].aufruf++;
   aufruf = MacroTable[macro].aufruf;
   for(i=0; i<help.paramcount; i++)
   {
      if(!operand[i][0])
      {
         error = 25;
         return(FALSE);
      }
      zeiger = operand[i];
      help.params[i] = (unsigned int)getstatement();
      help.defd[i] = TRUE;
      if(nerror)
      {
         if((pass == 1) && (error == 24))
         {
            help.defd[i] = FALSE;
            nerror = FALSE;
            error = 255;
         }
         else
            return(FALSE);
      }
   }
   paramcount = help.paramcount;
   for(i=0; i<10; i++)
   {
      params[i] = help.params[i];
      defd[i] = help.defd[i];
   }
   actmacro = macro;
   lines = 0L;
   return(TRUE);
}

/******************************
 * Adressierungsart ermitteln *
 ******************************/

int adress()
{
   register int i = 0, num = 0, lenght = 0;
   char akt[4];
   BOOL dif = TRUE;
   
   if(!operand[0][0]) /* akku/implement */
      return(11);

   if(operand[0][0] == '#') /* immediate */
   {
      operand[0][0] = ' ';
      return(0);
   }

   lenght = strlen(operand[0])-1;
   akt[0] = operand[0][0];
   akt[1] = operand[0][lenght-2];
   akt[2] = operand[0][lenght-1];
   akt[3] = operand[0][lenght];

   while((num<5) && dif)
   {
      dif = FALSE;
      i = 0;
      while((i<4) && !dif)
      {
         if(addr[num][i] != 255)
            if(addr[num][i] != akt[i])
               dif = TRUE;
         i++;
      }
      num++;
   }
   if(dif)
      return(4);
   else
   {
      num--;
      if(addr[num][0] != 255)
         operand[0][0] = ' ';
      for(i=0;i<3;i++)
      {
         if(addr[num][i+1] != 255)
            operand[0][lenght-2+i] = '\0';
      }
      return(addr[num][4]);
   }
}

/**********************
 * Zeile assemblieren *
 **********************/

BOOL assline()
{
   register unsigned int oper = 0, adr;

   adr = adress();
   zeiger = operand[0];
   if((*zeiger == ' ') || (*zeiger == '!'))
      zeiger++;
   nerror = FALSE;
   oper = ((adr < 4) && (adr > 6) && (pass == 1)) ? 0 : getstatement();
   if(nerror)
   {
      if((pass != 1) || (error != 24))
         return(FALSE);
      else
      {
         error = 255;
         oper = 65535;
      }
   }
   if((oper > 255) || (operand[0][0] == '!'))
   {
      switch(adr)
      {
         case 4:
            adr = 1;
            if(opcodes[mnemonic][adr] == 0xff)
               adr = 9;
            break;
         case 5:
            adr = 2;
            break;
         case 6:
            adr = 3;
            break;
         case 0:
         case 7:
         case 8:
            if(pass == 2)
            {
               error = 30;
               return(FALSE);
            }
      }
   }
   else
   {
      if((adr == 4) && (opcodes[mnemonic][adr] == 0xff))
         if(opcodes[mnemonic][1] == 0xff)
            adr = 9;
         else
            adr = 1;
   }

   if(opcodes[mnemonic][adr] == 0xff)
   {
      error = 31;
      return(FALSE);
   }
   linelenght = laenge[adr];
   over = oper;
   aver = adr;
   return(TRUE);
}

/*******************************
 * Opcodes für Zeile erstellen *
 *******************************/

BOOL makebytes()
{
   zeile[0] = opcodes[mnemonic][aver];
   if(aver == 11)
      return(TRUE);
   if(aver != 9)
   {
      zeile[1] = (unsigned char)(over - 256 * (over / 256));
      zeile[2] = (unsigned char)(over / 256);
   }
   else
   {
      if((over > (pc+2)) ? ((over-pc)>129) : ((pc-over)>126))
      {
         error = 33;
         return(FALSE);
      }
      zeile[1] = (unsigned char)(over - (pc + 2));
   }
   return(TRUE);
}

/**********************************
 * Bytes in Objektdatei speichern *
 **********************************/

BOOL outbytes()
{
   register char i = 0;

   while(i<linelenght)
   {
      outbuffer[pos] = zeile[i];
      pos++;
      if(pos == 512)
      {
         if(!ObjectHandle)
         {
            error = 40;
            return(FALSE);
         }
         if(Write(ObjectHandle, outbuffer, 512L) != 512L)
         {
            error = 35;
            return(FALSE);
         }
         pos = 0;
      }
      i++;
   }
   return(TRUE);
}

/*****************************
 * Einstellungen abspeichern *
 *****************************/

BOOL saveeinst()
{
   struct FileHandle *EinstHandle;

   error = 54;
   refreshstatus();
   error = 255;
   if(!(EinstHandle = (struct FileHandle *)
      Open("s:CA.prefs", MODE_NEWFILE)))
   {
      error = 44;
      return(FALSE);
   }
   if(Write(EinstHandle, &Einst, (long)sizeof(struct Einstellungen)) !=
      (long)sizeof(struct Einstellungen))
   {
      error = 44;
      Close(EinstHandle);
      return(FALSE);
   }
   Close(EinstHandle);
   return(TRUE);
}

/*******************************
 * Konvertierungstabelle laden *
 *******************************/

BOOL getname();
BOOL loadkonverttable()
{
   unsigned char konvtable[256], num[2][128];
   unsigned int i, u;
   unsigned long number1, number2;

   konvtable[0] = '\0';
   if(!getname("Name der Konvertierungstabelle:", konvtable))
      return(FALSE);
   error = 52;
   refreshstatus();
   error = 255;
   MacroPointer = MacroStack;
   IncludePointer = IncludeStack;
   strcpy(IncludePointer->lastfile, dateistrbuffer);
   IncludePointer->lineafter = 0L;
   IncludePointer++;
   endbuffer = (LONG) mainbuffer;
   actposition = (char *)endbuffer;
   actlenght = 0L;
   *mainbuffer = 0;

   while(getline())
   {
      num[0][0] = num[1][0] = '\0';
      zeiger = workbuffer;
      if(*zeiger == ';')
         continue;
      for(i=0; i<2; i++)
      {
         while((*zeiger == ' ') || (*zeiger == 0x09))
            zeiger++;
         u = 0;
         while((*zeiger != ' ') && (*zeiger != 0x09) && (*zeiger))
         {
            num[i][u] = *zeiger;
            u++;
            zeiger++;
         }
         num[i][u] = '\0';
      }
      zeiger = num[0];
      number1 = getnumber();
      if(nerror)
         break;
      zeiger = num[1];
      number2 = getnumber();
      if(nerror)
         break;
      for(i=(unsigned int)number1; i<256; i++, number2++)
         Einst.converttable[i] = (unsigned char)number2;
   }
   if(SourceHandle)
      Close(SourceHandle);
   SourceHandle = 0L;
   actname[0] = '\0';
   lines = completelines = 0L;
   return(TRUE);
}

/***********************
 * Einstellungen laden *
 ***********************/

BOOL loadeinst()
{
   struct FileHandle *EinstHandle;

   error = 53;
   refreshstatus();
   error = 255;
   if(!(EinstHandle = (struct FileHandle *)
      Open("s:CA.prefs", MODE_OLDFILE)))
   {
      error = 45;
      return(FALSE);
   }
   if(Read(EinstHandle, &Einst, (long)sizeof(struct Einstellungen)) !=
      (long)sizeof(struct Einstellungen))
   {
      error = 45;
      Close(EinstHandle);
      return(FALSE);
   }
   Close(EinstHandle);
   return(TRUE);
}

/******************************************
 * Pass 1 : Labeldefinitionen durchführen *
 ******************************************/

void passone()
{
   register unsigned int oldmacro = 0, dejafait = 0;
   struct Message *GetMsg();
   struct IntuiMessage *message;
   ULONG MessageClass;

   SourceHandle = 0L;
   MacroPointer = MacroStack;
   IncludePointer = IncludeStack;
   strcpy(IncludePointer->lastfile, srcname);
   IncludePointer->lineafter = 0L;
   IncludePointer++;
   endbuffer = (LONG) mainbuffer;
   actposition = (char *)endbuffer;
   *mainbuffer = 0;
   actlenght = 0L;
   macroup = MacroMem;
   labelnumber = 0L;
   macronumber = blockcounter = actmacro = 0;
   paramcount = 0;
   for(oldmacro = 0; oldmacro < 10; oldmacro++)
      params[oldmacro] = 0;
   aufruf = 0;
   oldmacro = 0;

   pass = 1;
   completelines = lines = 0L;
   start = pc = 0xc000;
   define = TRUE;
   refreshstatus();

   FOREVER
   {
      if(dejafait == Einst.delay)
      {
         dejafait = 0;
         refreshstatus();
         if(message = (struct IntuiMessage *)
            GetMsg(MainWindow->UserPort))
         {
            MessageClass = message->Class;
            ReplyMsg(message);
            if(MessageClass == GADGETUP)
            {
               error = 37;
               break;
            }
         }
      }
      dejafait++;
      linelenght = 0;
      if(!getline())
         break;
      if(!divideline())
         break;
      oldmacro = macronumber;
      if(pseudo != PSEUDOS)
      {
         if(!dopseudos())
            break;
         pc += linelenght;
      }
      if(mnemonic != MNEMONICS)
      {
         if(!assline())
            break;
         pc += linelenght;
      }
      if(macro != oldmacro)
         if(!domacro())
            break;
   }
   remarkblock();
}

/**************************************************
 * Pass 2 : Eigentliche Assemblierung durchführen *
 **************************************************/

void passtwo()
{
   register unsigned int i = 0, dejafait = 0;
   struct Message *GetMsg();
   struct IntuiMessage *message;
   ULONG MessageClass;
   char pstring[320];
   unsigned int oldpc;

   SourceHandle = ObjectHandle = 0L;
   MacroPointer = MacroStack;
   IncludePointer = IncludeStack;
   strcpy(IncludePointer->lastfile, srcname);
   IncludePointer->lineafter = 0L;
   IncludePointer++;
   endbuffer = (LONG) mainbuffer;
   actposition = (char *)endbuffer;
   *mainbuffer = 0;
   actlenght = 0L;
   paramcount = pos = 0;
   objname[0] = '\0';
   for(i = 0; i < 10; i++)
      params[i] = 0;
   aufruf = 0;
   for(i = 0; i < macronumber; i++)
      MacroTable[i].aufruf = 0;

   pass = 2;
   completelines = lines = 0L;
   pc = start;
   define = TRUE;
   refreshstatus();

   FOREVER
   {
      printed = FALSE;
      if(dejafait == Einst.delay)
      {
         dejafait = 0;
         refreshstatus();
         if(message = (struct IntuiMessage *)
            GetMsg(MainWindow->UserPort))
         {
            MessageClass = message->Class;
            ReplyMsg(message);
            if(MessageClass == GADGETUP)
            {
               error = 37;
               break;
            }
         }
      }
      dejafait++;
      linelenght = 0;
      oldpc = pc;
      if(!getline())
         break;
      if(!divideline())
         break;
      if(pseudo != PSEUDOS)
      {
         if(!dopseudos())
            break;
         pc += linelenght;
         if(!outbytes())
            break;
      }
      if(mnemonic != MNEMONICS)
      {
         if(!assline())
            break;
         if(!makebytes())
            break;
         pc += linelenght;
         if(!outbytes())
            break;
      }
      if(macro != macronumber)
      {
         if(!domacro())
            break;
      }
      if(prtflag && !printed)
      {
         sprintf(pstring, "%7lu : %04x ", completelines, oldpc);
         for(i=0; i<((linelenght > 3) ? 3 : linelenght); i++)
            sprintf(&pstring[15+i*3], "%02x ", zeile[i]);
         for(;i<3;i++)
            sprintf(&pstring[15+i*3], "   ");
         sprintf(&pstring[24], "%s\n", workbuffer);
         if((Write(PrintHandle, pstring, (long)strlen(pstring))) !=
            (long)strlen(pstring))
         {
            error = 60;
            break;
         }
      }
   }
   if(error == 255)
   {
      if(ObjectHandle)
      {
         if(Write(ObjectHandle, outbuffer, (long)pos) != (long)pos)
            error = 36;
      }
      else
         error = 40;
   }
   if(ObjectHandle)
   {
      Close(ObjectHandle);
      ObjectHandle = 0L;
   }
}

/**********************
 * Informationswindow *
 **********************/

BOOL information()
{
   struct Window *InfoWindow;
   struct Message *GetMsg();
   struct IntuiMessage *message;

   sprintf(InfoText5.IText, "       Labeltabelle:  %8lu Byte", Einst.labellenght);
   sprintf(InfoText6.IText, "       Makrotabelle:  %8lu Byte", Einst.macrotablelenght);
   sprintf(InfoText7.IText, "       Makrospeicher: %8lu Byte", Einst.macromemlenght);

   InfoNewWindow.LeftEdge = MainWindow->LeftEdge+20;
   InfoNewWindow.TopEdge = MainWindow->TopEdge+5;

   if(!(InfoWindow = (struct Window *)
      OpenWindow(&InfoNewWindow)))
   {
      error = 43;
      return(FALSE);
   }
   PrintIText(InfoWindow->RPort, &InfoText1, 0L, 0L);
   DrawBorder(InfoWindow->RPort, &InfoBorder1, 0L, 0L);
   WaitPort(InfoWindow->UserPort);
   message = (struct IntuiMessage *)GetMsg(InfoWindow->UserPort);
   ReplyMsg(message);
   CloseWindow(InfoWindow);
   return(TRUE);
}

/*********************
 * Dateinameneingabe *
 *********************/

BOOL getname(uebersch, string)
char *uebersch, *string;
{
   struct Window *DateiWindow;
   struct Message *GetMsg();
   struct IntuiMessage *message;
   USHORT MessageClass;

   if (OS20)
   {
      if (DateiReq(string,uebersch,"~(#?.info)"))
      {  strcpy(dateistrbuffer,string);
         return TRUE;
      }
      else
         return FALSE;
   }

   DateiNewWindow.LeftEdge = MainWindow->LeftEdge+12;
   DateiNewWindow.TopEdge = MainWindow->TopEdge+56;

   DateiText1.IText = uebersch;
   strcpy(dateistrbuffer, string);
   DateiStringInfo.BufferPos = strlen(string);

   if(!(DateiWindow = (struct Window *)
      OpenWindow(&DateiNewWindow)))
   {
      error = 43;
      return(FALSE);
   }
   PrintIText(DateiWindow->RPort, &DateiText1, 0L, 0L);
   ActivateGadget(&DateiGadget1, DateiWindow, NULL);
   WaitPort(DateiWindow->UserPort);
   message = GetMsg(DateiWindow->UserPort);
   MessageClass = message->Class;
   ReplyMsg(message);
   CloseWindow(DateiWindow);
   return((MessageClass & GADGETUP) ? TRUE : FALSE);
}

/**************************
 * Objektdatei übertragen *
 **************************/

BOOL transfer()
{
   struct FileHandle *ParHandle = 0L;
   unsigned long lenght = 512L;

   error = 255;
   if(!getname("Zu übertragende Datei:", objname))
      return(FALSE);

   if(!(ObjectHandle = (struct FileHandle *)
      Open(dateistrbuffer, MODE_OLDFILE)))
   {
      error = 34;
      return(FALSE);
   }
   if(!(ParHandle = (struct FileHandle *)
      Open("par:", MODE_OLDFILE)))
   {
      error = 46;
      return(FALSE);
   }
   error = 49;
   refreshstatus();
   error = 255;
   while(lenght == 512L)
   {
      lenght = Read(ObjectHandle, outbuffer, 512L);
      if(IoErr() > 100)
      {
         error = 47;
         break;
      }
      if(Write(ParHandle, outbuffer, lenght) != lenght)
      {
         error = 48;
         break;
      }
   }
   Close(ObjectHandle);
   Close(ParHandle);
   return((error == 255) ? TRUE : FALSE);
}

/***********************
 * Source-Code drucken *
 ***********************/

BOOL printsource()
{
   prtflag = (prtflag) ? FALSE : TRUE;
   if(prtflag)
   {
      if(!(getname("Druckdatei:", prtname)))
      {
         prtflag = FALSE;
         return(FALSE);
      }
      strcpy(prtname, dateistrbuffer);
      error = 57;
   }
   else
      error = 58;
   return(FALSE);
}

/***********************
 * Tabellen ausdrucken *
 ***********************/

BOOL printtabs(number)
char number;
{
   char pstring[100], pstring2[100], pstring3[100];
   register unsigned long counter, end;

   if(!(getname("Druckdatei:", prtname)))
      return(FALSE);
   strcpy(prtname, dateistrbuffer);
   if(!(PrintHandle = append(prtname)))
      error = 59;
   error = 61;
   refreshstatus();
   pstring[0] = pstring2[0] = pstring3[0] = '\0';
   switch(number)
   {
      case 0:
         end = (unsigned long)labelnumber;
         sprintf(pstring, "\nLabeltabelle: %lu Einträge\n\n", (unsigned long)labelnumber);
         if(end)
         {
            strcpy(pstring2, "Labelname                         dez.   hex.\n");
            strcpy(pstring3, "---------------------------------------------\n");
         }
         break;
      case 1:
         end = (unsigned long)macronumber;
         sprintf(pstring, "\nMakrotabelle: %lu Einträge\n\n", (unsigned long)macronumber);
         if(end)
         {
            strcpy(pstring2, "Makroname                         Länge  Parameter\n");
            strcpy(pstring3, "--------------------------------------------------\n");
         }
         break;
      case 2:
         end = (unsigned long)blockcounter;
         sprintf(pstring, "\nBlocktabelle: %u Einträge\n\n", blockcounter);
         if(end)
         {
            strcpy(pstring2, "von    bis    von     bis    Länge  Dateinamen\n");
            strcpy(pstring3, "--------------------------------------------------------------------\n");
         }
         break;
   }
   if(((Write(PrintHandle, pstring, (long)strlen(pstring))) !=
      (long)strlen(pstring)) ||
      ((Write(PrintHandle, pstring2, (long)strlen(pstring2))) !=
      (long)strlen(pstring2)) ||
      ((Write(PrintHandle, pstring3, (long)strlen(pstring3))) !=
      (long)strlen(pstring3)))
   {
      error = 60;
      Close(PrintHandle);
      return(FALSE);
   }
   for(counter = 0L; counter<end; counter++)
   {
      switch(number)
      {
         case 0:
            sprintf(pstring, "%-32.32s  %5u  %04x\n",
               LabelTable[counter].name, LabelTable[counter].wert,
               LabelTable[counter].wert);
            break;
         case 1:
            sprintf(pstring, "%-32.32s  %5lu        %2u\n",
               MacroTable[counter].name, MacroTable[counter].lenght,
               MacroTable[counter].paramcount);
            break;
         case 2:
            sprintf(pstring, "%04x - %04x  %5u - %5u   %5u  %-32.32s\n",
               BlockTable[counter].begin, BlockTable[counter].end,
               BlockTable[counter].begin, BlockTable[counter].end,
               (BlockTable[counter].end-BlockTable[counter].begin),
               BlockTable[counter].name);
            break;
      }
      if((Write(PrintHandle, pstring, (long)strlen(pstring))) !=
         (long)strlen(pstring))
      {
         error = 60;
         Close(PrintHandle);
         return(FALSE);
      }
   }
   Close(PrintHandle);
   error = 255;
   return(TRUE);
}

/*******************************************************************
 * Labels alphabetisch sortieren (Algorithmus: Straight Insertion) *
 *******************************************************************/

char stricmp(a, b)
register char *a, *b;
{
   while(*a && (tolower(*a) == tolower(*b)))
   {
      a++;
      b++;
   }
   return(*a ? (tolower(*a) - tolower(*b)) : 0);
}

void sortthem()
{
   struct Label helplabel;
   register unsigned long i = 0L, j = 0L;

   error = 56;
   refreshstatus();
   if(labelnumber > 1L)
   {
      for(i=1L; i<labelnumber; i++)
      {
         if(stricmp(LabelTable[i].name, LabelTable[i-1L].name) < 0)
         {
            helplabel = LabelTable[i];
            for(j=i; j; j--)
            {
               LabelTable[j] = LabelTable[j-1L];
               if(stricmp(helplabel.name, LabelTable[j-2L].name) > 0)
               {
                  LabelTable[j-1L] = helplabel;
                  break;
               }
            }
         }
      }
   }
   error = 255;
   refreshstatus();
}

/****************************
 * Alle Texte neu schreiben *
 ****************************/

void redrawit(upper, number)
unsigned long upper;
USHORT number;
{
   register unsigned long i = 0;
   register int u;

   for(i=0; i<15; i++)
   {
      switch(number)
      {
         case 0:
            if((i+upper) < labelnumber)
               sprintf(TaText[i], "%-32.32s  %5u    $%04x",
                     LabelTable[i+upper].name, LabelTable[i+upper].wert,
                     LabelTable[i+upper].wert);
            else
               strcpy(TaText[i], "                                                 ");
            break;
         case 1:
            if((i+upper) < (unsigned long)macronumber)
               sprintf(TaText[i], "%-32.32s  %5lu        %2u",
                     MacroTable[i+upper].name, MacroTable[i+upper].lenght,
                     MacroTable[i+upper].paramcount);
            else
               strcpy(TaText[i], "                                                 ");
            break;
         case 2:
            if((i+upper) < (unsigned long)blockcounter)
               sprintf(TaText[i], "%04x-%04x  %5u %-32.32s",
                     BlockTable[i+upper].begin, BlockTable[i+upper].end,
                     (BlockTable[i+upper].end-BlockTable[i+upper].begin),
                     BlockTable[i+upper].name);
            else
               strcpy(TaText[i], "                                                 ");
            break;
         case 3:
            if((i+upper) < (unsigned long)MNEMONICS)
            {
               sprintf(TaText[i], "%3.3s                                              ",
                       mnemonics[i+upper]);
               for(u=0; u<12; u++)
                  TaText[i][5+u*4] = 
                     (opcodes[i+upper][u] == 0xff) ? ' ' : '*';
            }
            else
               strcpy(TaText[i], "                                                 ");
            break;
      }
   }
}

/***********************
 * Einstellungenwindow *
 ***********************/

BOOL doeinstellungen()
{
   struct Window *EinstWindow;
   struct Message *GetMsg();
   struct IntuiMessage *message;
   struct Einstellungen Ein;
   ULONG MessageClass = 0L, freechip = 0L, freefast = 0L;
   USHORT GadgetID = 0;
   BOOL refr = TRUE;

   Ein = Einst;
   sprintf(einst1strbuffer, "%lu", 
      (Einst1StringInfo.LongInt = Ein.labellenght/(long)sizeof(struct Label)));
   sprintf(einst2strbuffer, "%lu",
      (Einst1StringInfo.LongInt =  Ein.macrotablelenght/(long)sizeof(struct Macro)));
   sprintf(einst3strbuffer, "%lu", Ein.macromemlenght);
   sprintf(einst4strbuffer, "%u", Ein.delay);
   Einst1StringInfo.BufferPos = strlen(einst1strbuffer);
   Einst2StringInfo.BufferPos = strlen(einst2strbuffer);
   Einst3StringInfo.BufferPos = strlen(einst3strbuffer);
   Einst4StringInfo.BufferPos = strlen(einst4strbuffer);
   if(Ein.sort)
      EinstGadget6.Flags |= SELECTED;
   else
      EinstGadget6.Flags &= ~SELECTED;
   freechip = (unsigned long)AvailMem(MEMF_CHIP | MEMF_LARGEST);
   freefast = (unsigned long)AvailMem(MEMF_FAST | MEMF_LARGEST);

   if(!(EinstWindow = (struct Window *)
      OpenWindow(&EinstNewWindow)))
   {
      error = 43;
      return(FALSE);
   }
   PrintIText(EinstWindow->RPort, &EinstText4, 0L, 0L);
   ActivateGadget(&EinstGadget1, EinstWindow, NULL);

   while((MessageClass != CLOSEWINDOW) && (GadgetID != 5))
   {
      if(refr)
      {
         refr = FALSE;
         sprintf(EinstText4.IText, " = %8lu Byte", Ein.labellenght);
         sprintf(EinstText5.IText, " = %8lu Byte", Ein.macrotablelenght);
         PrintIText(EinstWindow->RPort, &EinstText4, 0L, 0L);
      }
      WaitPort(EinstWindow->UserPort);
      message = GetMsg(EinstWindow->UserPort);
      MessageClass = message->Class;
      GadgetID = (USHORT)(((struct Gadget *)(message->IAddress))->GadgetID);
      ReplyMsg(message);

      switch(GadgetID)
      {
         case 1:
            if(((Ein.labellenght = Einst1StringInfo.LongInt *
                       (long)sizeof(struct Label)) > freechip) &&
                (Ein.labellenght > freefast))
                Ein.labellenght = 0L;
            refr = TRUE;
            ActivateGadget(&EinstGadget2, EinstWindow, NULL);
            break;
         case 2:
            if(((Ein.macrotablelenght = Einst2StringInfo.LongInt *
                       (long)sizeof(struct Macro)) > freechip) &&
                (Ein.labellenght > freefast))
                Ein.labellenght = 0L;
            refr = TRUE;
            ActivateGadget(&EinstGadget3, EinstWindow, NULL);
            break;
         case 3:
            Ein.macromemlenght = Einst3StringInfo.LongInt;
            ActivateGadget(&EinstGadget4, EinstWindow, NULL);
            break;
         case 4:
            Ein.delay = (unsigned int)Einst4StringInfo.LongInt;
            ActivateGadget(&EinstGadget1, EinstWindow, NULL);
            break;
         case 6:
            Ein.sort = 1-Ein.sort;
            break;
      }
   }
   freeit();
   if(MessageClass != CLOSEWINDOW)
   {
      Einst.macromemlenght = Ein.macromemlenght;
      Einst.macrotablelenght = Ein.macrotablelenght;
      Einst.labellenght = Ein.labellenght;
      Einst.delay = Ein.delay;
      Einst.sort = Ein.sort;
   }
   labelnumber = 0L;
   macronumber = actmacro = 0;
   EinstNewWindow.LeftEdge = EinstWindow->LeftEdge;
   EinstNewWindow.TopEdge = EinstWindow->TopEdge;
   CloseWindow(EinstWindow);
   return(TRUE);
}

/******************
 * Tabellenwindow *
 ******************/

BOOL dotables(number)
USHORT number;
{
   struct Window *TableWindow;
   struct Gadget *ActG;
   struct Message *GetMsg();
   struct IntuiMessage *message;
   ULONG MessageClass;
   USHORT flag = 0;
   register int i;
   unsigned int quot;
   unsigned long max, upper, oldupper;

   TaProp1.VertPot = max = upper = 0;
   switch(number)
   {
      case 0:
         max = labelnumber;
         strcpy(TaText1.IText, "Labelname                         dez      hex    ");     
         break;
      case 1:
         max = (unsigned long)macronumber;
         strcpy(TaText1.IText, "Makroname                         Länge Parameter ");
         break;
      case 2:
         max = (unsigned long)blockcounter;    
         strcpy(TaText1.IText, "von  bis   Länge  Dateiname                       ");
         break;
      case 3:
         max = (unsigned long)MNEMONICS;
         strcpy(TaText1.IText, "    IM  AB  AX  AY  ZP  ZX  ZY  ID  DI  RE  IN  AI");
         break;
   }
   TaProp1.VertBody = (max < 16) ? 0xffff : (0xffff / max) * 15;

   if(!(TableWindow = (struct Window *)
      OpenWindow(&TableNewWindow)))
   {
      error = 43;
      return(FALSE);
   }
   DrawBorder(TableWindow->RPort, &TaBorder1, 0L, 0L);
   DrawBorder(TableWindow->RPort, &TaBorder3, 415L, 22L);
   DrawBorder(TableWindow->RPort, &TaBorder3, 415L, 138L);
   for(i=0; i<15; i++)
   {
      TaIntuiText[i] = TaTText;
      TaIntuiText[i].NextText = &TaIntuiText[i+1];
      TaIntuiText[i].TopEdge = 24 + i * 8;
      TaIntuiText[i].IText = TaText[i];
      TaText[i][0] = '\0';
   }
   TaIntuiText[14].NextText = NULL;
   redrawit(upper, number);
   PrintIText(TableWindow->RPort, &TaText1, 0L, 0L); 
   PrintIText(TableWindow->RPort, TaIntuiText, 0L, 0L);

   do
   {
      message = (struct IntuiMessage *)GetMsg(TableWindow->UserPort);
      if(!message && !flag)
      {
         Wait(1L << TableWindow->UserPort->mp_SigBit);
         continue;
      }

      if(message)
      {
         MessageClass = message->Class;
         ReplyMsg(message);
         if(MessageClass & GADGETDOWN)
         {
            ActG = message->IAddress;
            flag = ActG->GadgetID;
         }
         if((MessageClass & GADGETUP) || (MessageClass & CLOSEWINDOW))
            flag = 0;
      }

      if(flag && !((ActG->Flags) & SELECTED))
         flag = 0;
      oldupper = upper;
      quot = (0xffff/(max-15));
      switch(flag)
      {
         case 2:
            if((upper < (max-15L)) && (max > 15L))
            {
               upper++;
               TaProp1.VertPot = upper*quot;
               RefreshGadgets(&TaGadget3, TableWindow, NULL);
            }
            break;
         case 1:
            if(upper > 0)
            {
               upper--;
               TaProp1.VertPot = upper*quot;
               RefreshGadgets(&TaGadget3, TableWindow, NULL);
            }
            break;
      }
      if((upper * quot) != TaProp1.VertPot)
      {
            upper = (max < 16) ?
                  0 : TaProp1.VertPot/quot;
            if(((upper+15) > max) && (max > 15))
               upper = max-15;
      }
      if(upper != oldupper)
      {
         redrawit(upper, number);
         PrintIText(TableWindow->RPort, &TaText1, 0L, 0L); 
         PrintIText(TableWindow->RPort, TaIntuiText, 0L, 0L);
      }
   } while(!(MessageClass & CLOSEWINDOW));
   TableNewWindow.LeftEdge = TableWindow->LeftEdge;
   TableNewWindow.TopEdge = TableWindow->TopEdge;
   CloseWindow(TableWindow);
   return(TRUE);
}

/******************************
 * Menüauswertung durchführen *
 ******************************/

void domenus(menunumber)
USHORT menunumber;
{
   USHORT Menu, MenuItem;

   Menu = MENUNUM(menunumber);
   MenuItem = ITEMNUM(menunumber);
   error = 255;

   ClearMenuStrip(MainWindow);
   switch(Menu)
   {
      case 0: /* Datei-Menü */
         switch(MenuItem)
         {
            case 0: /* Übertragen */
               transfer();
               break;
            case 1: /* Information */
               information();
               break;
            case 2: /* Beenden */
               freeit();
               closeall();
               exit(TRUE);
         }
         break;
      case 1: /* Tabellen-Menü */
         dotables(MenuItem);
         break;
      case 2: /* Einstellungen-Menü */
         switch(MenuItem)
         {
            case 0: /* Ändern */
               doeinstellungen();
               break;
            case 1: /* Speichern */
               saveeinst();
               break;
            case 2: /* Laden */
               loadeinst();
               break;
            case 3: /* KonTab laden */
               loadkonverttable();
               break;
         }
         break;
      case 3: /* Drucken-Menü */
         if(!MenuItem)
            printsource(); /* Source-Code */
         else
            printtabs(MenuItem-1); /* Tabellen */
         break;
   }
   pass = 0;
   SetMenuStrip(MainWindow, &MenuDatei);
   if(error != 255)
      refreshstatus();
}

/*****************
 * Hauptschleife *
 *****************/

void mainloop()
{
   struct Message *GetMsg();
   struct IntuiMessage *message;
   ULONG MessageClass;
   USHORT code;

   refreshstatus();
   ClearMenuStrip(MainWindow);
   information();
   SetMenuStrip(MainWindow, &MenuDatei);
   srcname[0] = '\0';

   FOREVER
   {
      pass = 0;
      WaitPort(MainWindow->UserPort);
      message = GetMsg(MainWindow->UserPort);
      MessageClass = message->Class;
      code = message->Code;
      ReplyMsg(message);
      if(MessageClass & CLOSEWINDOW)
         break;
      if(MessageClass & GADGETUP)
      {
         ClearMenuStrip(MainWindow);
         if(!(getname((char *)"Quelldateiname:", srcname)))
         {
            SetMenuStrip(MainWindow, &MenuDatei);
            continue;
         }
         strcpy(srcname, dateistrbuffer); 
         objname[0] = '\0';
         Gadget1.GadgetText = &GadgetText2;
         RefreshGadgets(&Gadget1, MainWindow, NULL);
         freeit();
         if(init())
         {
            error = 255;
            run = TRUE;
            passone();
            if(prtflag)
            {
               if(!(PrintHandle = append(prtname)))
                  error = 59;
            }               
            if(error == 255)                  
               passtwo();
            run = FALSE;
            if(prtflag)
            {
               if(PrintHandle)
                  Close(PrintHandle);
            }
            if(SourceHandle)
               Close(SourceHandle);
            SourceHandle = 0L;
            if(((error == 255) || (error == 37)) && Einst.sort)
               sortthem();
            refreshstatus();
         }
         Gadget1.GadgetText = &GadgetText1;
         RefreshGadgets(&Gadget1, MainWindow, NULL);
         SetMenuStrip(MainWindow, &MenuDatei);
      }
      if(MessageClass & MENUPICK)
      {
         domenus(code);
         refreshstatus();
      }
   }
}

/*********************************************************
 * Aufruf des FileRequesters der ASL-Library in C        *
 *                                                       *
 * Datum           : 18. November 1990                   *
 * Autor           : David Göhler                        *
 * Version         : 1.1                                 *
 * Letzte Änderung : 18. November 1990                   *
 *                                                       *
 * Compilieren mit DICE: dcc filereq.c -o filereqdemo    *
 *                                                       *
 *********************************************************/


#define FILENAMELEN 256

struct Library *AslBase;


/* Syntax  : BOOL DateiReq(filename,AnzeigeText,Show)

  Datum   : 04. November 1989

  Eingabe : filename     - Zeiger auf den Filenamen
            AnzeigeText  - Zeiger auf Text, der oben im Window steht
            Show         - Ein String, der ein Pattern enthält. Der FileRequester
                           zeigt dann nur Dateien an, die auf das Pattern passen.

  Ausgabe : FALSE        - Requester mit Cancel verlassen
            TRUE         - neuer Dateiname ist gültig

  Funktion: Aufruf des 2.0-ASL-FileRequesters. Ein vereinfachtes Beispiel.
            Läuft nur unter 2.0
*/

BOOL DateiReqD(char *filename,char *AnzeigeText,char *Show, BOOL dir)
{
  struct FileRequester *FR;
  char zwfile[FILENAMELEN];
  char zwdir [FILENAMELEN];
  char *cpoint,c;
  BOOL retcode = FALSE;
  ULONG extflags1;

  if (dir) extflags1 = FIL1F_NOFILES; else extflags1 = FIL1F_MATCHDIRS;

  if (AslBase = (struct Library *)OpenLibrary(AslName,37))
  {
     // String in filename und dirname aufteilen
     cpoint = PathPart(filename);
     c = *cpoint; *cpoint = '\0';
     strcpy(zwdir,filename);
     if (c=='/') {  *cpoint++=c; } else { *cpoint = c; }
     strcpy(zwfile,cpoint);

     if (FR = AllocAslRequestTags( ASL_FileRequest,
                                   ASL_Hail,         AnzeigeText,
                                   ASL_Window,       0L,
                                   ASL_File,         zwfile,
                                   ASL_Dir,          zwdir,
                                   ASL_FuncFlags,    FILF_PATGAD,
                                   ASL_ExtFlags1,    extflags1,
                                   ASL_Pattern,      Show,
                                   TAG_DONE ))
     {
        if (RequestFile(FR))
        {
           strcpy(filename,FR->rf_Dir);
           AddPart(filename,FR->rf_File,FILENAMELEN);
           retcode = TRUE;
        }
        FreeFileRequest(FR);
     }
     CloseLibrary((struct Library *)AslBase);
  }
  return retcode;
}

BOOL DateiReq(char *filename,char *AnzeigeText,char *Show)
{
    return DateiReqD(filename,AnzeigeText,Show,FALSE);
}


/*****************
 * Hauptprogramm *
 *****************/

void main()
{
   openall();
   mainloop();
   freeit();
   closeall();
}



