/*
   Chip2Fast  - zum Einbinden von Chip als Fast-Mem

      entstanden aus

   Arguments  -- eine CLI-Hülle für Programme ab Workbench 2.04
 */

/*
 *  allgemeine Include-Dateien
 */

#include <string.h>
#include <stdlib.h>

/*
 *  spezielle Amiga-Include-Dateien
 */

#include <dos/dos.h>
#include <dos/rdargs.h>
#include <exec/memory.h>
#include <exec/types.h>
#include <exec/execbase.h>
#include <clib/exec_protos.h>
#include <clib/dos_protos.h>

/*
 * Defines, die bei einer Kopie zu ändern sind
 */

#define PROGNAME "Chip2Fast"          /* Default-Name des Programms     */
#define VERSION  "1.0"                /* Versions-Nummer 1.0 am Anfang! */
#define AUTHOR   "David Göhler"       /* Name des Autors                */
#define DATE     "28.02.96"           /* Datum der letzten Änderung     */
#define ENVVAR   PROGNAME             /* Name einer ENV-Variable        */

/*
 * dauerhafte define's, die kaum einer Änderung bedürfen
 */

#define NAMELEN  255                  /* Länge des Programmnamens       */
#define LINELEN  10000                /* Zeilenlänge im Makefile        */
#define BUFLEN   200                  /* Pufferlänge für Datei-Pattern  */

/*
 * Default-Optionen
 */

#define DEFAULT_KBYTE     512
#define DEFAULT_PRIORITY  10
#define DEFAULT_TESTLEVEL 2
#define DEFAULT_NAME      "Chip2Fast Memory"

/*
 * falls ein GCC zum Einsatz kommt, DICE-Spezialitäten abwürgen
 */

#ifdef __GNUC__
#define __stkargs                     /* kennt der GCC nicht            */
#endif

const char VersionID      []="$VER: " PROGNAME " " VERSION " - © " AUTHOR " " DATE;
const char TemplateString []="KBYTE/N,PRI/K/N,NAME/K";
// enum       TemplateEnum     { KBYTE,  PRI,    NAME};

typedef struct {
       LONG *KByte;           /* wieviel KByte nehmen, default s.o. */
       LONG *priority;        /* mit welcher Priority */
       char *memname;         /* wie der Speicher heißen soll */
} Template;                   /* Für die Kommandozeile */

ULONG kbyte;
LONG  priority;
char  *memname;

/*
 * globale Variablen, die die Einstellungen per Kommandozeile darstellen
 */

char  EnvString [BUFLEN] = "";        /* für eine eventuelle Env-Variable */
char  progname  [NAMELEN]= PROGNAME;  /* Für Ausgaben bei Fehlermeldungen */

Template CommandLineVars = {          /* Template-Struktur für ReadArgs   */
     0L, 0L, 0L
};

/*
 * externe Referenzen
 */

extern struct ExecBase *SysBase;   /* Für den Versionstest */

/*
 * main-Kopf, für GCC-Nutzer mit Extrawurst
 */

main()
{
   struct RDArgs *rda;              /* nicht notwendigerweise global */
   long           rc  = RETURN_OK;  /* Return-Code von main          */

   /* dies Programm läuft nur ab Version 2.04 */
   if (SysBase->LibNode.lib_Version < 37)
   {  Write(Output(),"Wrong kickstart version, must 37.175 or higher\n",47);
      return RETURN_FAIL;
   }

   /* wie heiße ich denn ? */
   if (!GetProgramName(progname,NAMELEN-1))   /* bei Fehlversuch */
   {  strncpy(progname,PROGNAME,NAMELEN-1); } /* Default kopieren */

   /* nun die Kommandozeilenauswertung erledigen - per Systemaufruf */
   if (rda = ReadArgs ((UBYTE *)TemplateString,(LONG *) &CommandLineVars,NULL))
   {
      APTR chipmem;

      if (CommandLineVars.priority == 0)
      {  priority = DEFAULT_PRIORITY; }
      else
      {  priority = *(CommandLineVars.priority); }

      if (CommandLineVars.memname == 0)
      {  if (memname = AllocMem(strlen(DEFAULT_NAME)+1,MEMF_PUBLIC))
         {  strncpy(memname, DEFAULT_NAME, NAMELEN-1); }
         else
         {  memname = 0L; }
      }
      else
      {  if (memname = AllocMem(strlen(CommandLineVars.memname)+1,MEMF_PUBLIC))
         { strncpy(memname, CommandLineVars.memname, NAMELEN-1); }
         else
         {  memname = 0L; }
      }

      if (CommandLineVars.KByte == 0)
      {  kbyte = DEFAULT_KBYTE; }
      else
      {  kbyte = *(CommandLineVars.KByte); }

      if (chipmem = AllocMem(kbyte*1024,MEMF_CHIP))
      {  AddMemList(kbyte*1024,MEMF_PUBLIC|MEMF_FAST,priority,chipmem,memname); }
      else
      {  Printf("Konnte %ld KByte nicht allozieren\n",kbyte); }

      /* alloziertes wieder freigeben */
      FreeArgs(rda);
   }
   else
   {  rc = RETURN_ERROR; }

   /* bei einem Fehler, den Fehler ausgeben */
   if (rc != RETURN_OK) PrintFault(IoErr(),progname);

   return rc;
}

