#ifndef XPKMASTER_DEBUF_C
#define XPKMASTER_DEBUG_C

/* Routinesheader

	Name:		debug.c
	Main:		xpkmaster
	Versionstring:	$VER: debug.c 1.1 (20.10.96)
	Author:		SDI
	Distribution:	PD
	Description:	the debug stuff

 1.0   05.10.96 : first real version
 1.1   20.10.96 : added the external debug modes
 1.2   21.10.96 : changed debug totally
*/

#include <exec/types.h>
#include <exec/memory.h>
#include <pragma/exec_lib.h>
#include <pragma/dos_lib.h>

typedef void (*putchtype) ();

#ifdef __MAXON__
  #define __asm
#endif

extern KPutChar(LONG);
extern DPutChar(LONG);
extern struct DosLibrary *DOSBase;
extern void DoDebug(UBYTE mode, STRPTR fmt, APTR data);

static UBYTE Mode = 0xFF;

static void __asm serfunc(register __d0 UBYTE c, register __a3 ULONG pd)
{ KPutChar(c ? c : '\n'); }

static void __asm parfunc(register __d0 UBYTE c, register __a3 ULONG pd)
{ DPutChar(c ? c : '\n'); }

static void __asm normfunc(register __d0 UBYTE c, register __a3 ULONG pd)
{
  UBYTE d = c;

  if(!d)
    d = '\n';

  Write(pd, &d, 1);
}

void DebugError(STRPTR format, ...)
{
  DoDebug(1, format, (APTR)((ULONG)(&format)+sizeof(STRPTR)));
}

void DebugRunTime(STRPTR format, ...)
{
  DoDebug(0, format, (APTR)((ULONG)(&format)+sizeof(STRPTR)));
}

void DoDebug(UBYTE mode, STRPTR fmt, APTR data)
{
  ULONG fh = 0;
  void __asm (*function)(register __d0 UBYTE, register __a3 ULONG) = 0;

  Forbid();

  if(Mode == 0xFF)
  {
    struct FileInfoBlock *fib;
    if((fib = (struct FileInfoBlock *) AllocMem(sizeof(struct FileInfoBlock), MEMF_ANY)))
    {
      ULONG lock;
      if((lock = Lock("LIBS:xpkmaster.library", SHARED_LOCK)))
      {
        if(Examine(lock,fib))
        {
          switch(*fib->fib_Comment)
          {
          case '0' : Mode = 0; break;
          case '2' : Mode = 2; break;
          case 'S' : Mode = 3; break;
          case 'P' : Mode = 4; break;
          default: Mode = 1; break;
          }
        }
        else
          Mode = 1;
        UnLock(lock);
      }
      else
        Mode = 1;
      FreeMem(fib, sizeof(struct FileInfoBlock));
    }
    else
      Mode = 1;
  }

  switch(Mode)
  {
  case 1: case 2:
    if(mode || Mode == 2)
    {
      if((fh = Open("T:XpkMasterOut", MODE_READWRITE)))
      {
        Seek(fh, 0, OFFSET_END);
        function = normfunc;
      }
    } break;
  case 3: function = serfunc; break;
  case 4: function = parfunc; break;
  }

  if(function)
  {
    ULONG i, j = 32;
    UBYTE c;
    i = (ULONG) FindTask(0);

    do
    {
      j -= 4;
      if((c = ((i >> j) & 0xF) + '0') > '9')
        c += 'A' - '0' - 10;
      
      function(c, fh);
    } while(j);

    function(':', fh);

    RawDoFmt(fmt, data, (putchtype) function, (APTR) fh);
  }

  if(fh)
    Close(fh);

  Permit();
}

#endif /* XPKMASTER_DEBUG_C */
