/*    Dumpanalyse für Guru Ex.

      (c) M. Wilhelm 1988
         V1.0
         Apr. 1988            */

#include "exec/types.h"
#include "libraries/dos.h"
#include "functions.h"

#define  BufLng   140
#define  ErrCode  20L

main()            /* Aufruf: gxda  */

{
   long  Buff[BufLng/4];
   long  error = 0L;
   static int   stcode [] = { 16, 8, 4, 2, 1 };
   static char  Flags[] = {88,78,90,86,67};     /* die Prozessor Flags */
   /* Die Prozessor Flags   X  N  Z  V  C  */

   static char  *TrapMsg[] = {           /* die Fehlercodes für die Traps */
         "Bus Fehler",                          /* Bus Error */
         "Adress Fehler",                       /* Address Error */
         "Ungültige Instruktion",               /* Illegal Instruction */
         "Division durch Null",                 /* Zero Divide */
         "CHK Befehl erkannt",                  /* CHK Instruction */
         "TRAPV Befehl ausgeführt",             /* TRAPV Instruction */
         "Privilegierter Befehl im User Modus", /* Privilege Violation */
         "Trace",                               /* Tritt nicht auf */
         "Befehlscode 0xA.. erkannt",           /* Line 1010 Emulator */
         "Befehlscode 0xF.. erkannt" };         /* Line 1111 Emulator */

   int   i,tc,status;
   struct FileHandle *fh;        /* FileHandle für Dumpfile */

   /* Dumpfile eröffnen */
   if ((fh = Open("ram:Guru.dmp",MODE_OLDFILE)) == NULL)
   {  error = IoErr(); /* kein Guru Dumpfile gefunden */
      printf("\n\n*** Fehler bei Open Guru.dmp. Fehlernr. %ld\n\n",error);
      return(ErrCode);
   }

   if ((Read(fh,Buff,BufLng)) != BufLng)
   {  printf("\n\n*** Dumpfile hat nicht die richtige Länge.\n");
      printf("    Analyse des Dumps nicht möglich.\n\n");
      Close(fh);
      return(ErrCode);
   }

   Close(fh);  /* Jetzt haben wir alle Informationen */

   printf("\n\tGuru Ex Dump\n");
   tc=Buff[0] >> 16; status=Buff[0] & 0xffffL;
   printf("\tTrap Nr. %d: %s\n\n",tc,TrapMsg[tc-2]);
   printf("\tProzessor Status: ");

   /* Hier werden PC, SP und CCR ausgegeben */

   printf("PC=%08lx (%08lx), SP=%08lx,",Buff[1],Buff[1]-Buff[18],Buff[17]);
   printf(" CCR=");
   for (i=0; i < 5; i++)
   {
      if ((status & stcode[i]) == 0)
         putchar(45);  /* Minuszeichen, wenn Flag nicht gesetzt */
      else putchar(Flags[i]);  /* gesetzte Flags anzeigen */
   }

   /* Erst die Inhalte der Datenregister ausgeben */

   printf("\n\n\tRegister Inhalt:\n\t");

   for (i=2; i < 10; i++)
   {
      printf("D%d=%08lx",i-2,Buff[i]);
      if ((i==5) | (i==9)) printf("\n\t"); else printf(", ");
   }

   /* Jetzt sind die Adressregister dran */

   for (i=10; i < 17; i++)
   {
      printf("A%d=%08lx",i-10,Buff[i]);
      if ((i==13)|(i==16)) printf("\n\t"); else printf(", ");
   }

   /* Nun noch die letzten 32 Worten auf dem Stack */

   printf("\n\tStackinhalt nach Trap:\n\t");

   for (i=19; i < 35; i++)
   {
      printf("%04x  %04x  ",(short)(Buff[i]>>16),(short)(Buff[i]&0xffff));
      if (((i-19) & 3) == 3) printf("\n\t");
   }
   printf("\n");
   return(0L);
}
