/*******************************************************************************************

      BeebEmDOS main loop

      17 Jan 97   MHG   disc_reset 1-cold 0-warm
      17 feb 97   MHG   ctrl causes total reboot,once in


*******************************************************************************************/
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include "iostream.h"
#include "6502core.h"
#include "beebmem.h"
#include "sysvia.h"
#include "uservia.h"
//#include "beebbitm.h"
//#include "beebwin.h"
#include "disc8271.h"
#include "video.h"
#include "xvid.h"
#include "sound.h"
#include "keys.h"  //MHG

#define LIMITSPEED   1

#define SPEEDGAP   ((2000000*256)/RATE)

/*******************************************************************************************


      EXTERNALS


*******************************************************************************************/
extern "C" unsigned char  *aligned;
extern "C" void parse_gamefile(void);
extern "C" char *load_game(int a);
extern "C" char *get_disc_name(int a);
extern "C" int   save_file(char *name,char *buff,int len);
extern "C" unsigned char LookKey(void);
extern "C" void GetDOSMemory(void);
extern "C" void InitSound(void);
extern "C" void SetSampleRate(int);
extern "C" void InstallSBInterrupt(void);
extern "C" void TriggerSound(int a);
extern "C" void setrez(int a);
extern "C" void SetModeX(void);
extern "C" void SetBBCPalette(void);
extern "C" void SetHighSampleRate(int);
extern "C" void ClearSound(void);
extern "C" void insert_text(char *);
extern "C" void insert_char(char );
extern "C" void insert(void);
extern "C" void install_keyboard_interrupt(void);
extern   int   menutype;
extern   int   cursor_pos;
extern   "C"   int            soundon;
extern   int   TotalCycles;
extern   "C"      unsigned char  *soundflag;
extern   char  dummy[];
/*******************************************************************************************


      PROTOTYPES


*******************************************************************************************/
char  inkey(int a);
char  *menu(char *);
int   TranslateKey(int index, int *row, int *col) ;
extern "C" int   save_screen(char *);
/*******************************************************************************************


         DATA


*******************************************************************************************/


/*
						    BBC KEYBOARD


		    f0  f1  f2  f3  f4  f5  f6  f7  f8  f9  BRK
			 20  71  72  73  14  74  75  16  76  77  xx

		  !   "   #   $   %   &   '   (   )       =   ~   |
	ESC  1   2   3   4   5   6   7   8   9   0   -   ^   \   LFT   RGT
	 70  30	31	 11  12	13	 34  24	15	 25  27  17  18  78  19    79

																		{   p
	TAB    Q   W   E   R   T   Y   U   I   O   P   @   [   _		UP     DWN
	 60	 10  21  22  33  23  44  35  26  36  37  47  38  28   39     29

																+   *   }
  CPS  CTL  A   S   D   F   G   H   J   K   L   ;   :   ]    RET
	40		1	41  51  32  43  53  54  45  46  56  57  48  58   49

														<   >   ?
  SLK  SHF    Z   X   C   V   B   N   M   ,   .   /   SHF    DEL  CPY
	50	 00     61  42  52  63  64  55  65  66  67  68  00     59   69


								    SPACEBAR
									 62






		ESC	f1  f2  f3  f4       f5  f6  f7  f8     f9  f10  f11  f12     SRQ  SLK  BRK
		1     59  60  61  62       63  64  65  66     67  68   87   88      67   68   69

	    ~   !   @   #   $   %   ^   &   *   (   )   _   +   |
	    `   1   2   3   4   5   6   7   8   9   0   -   =   \   DEL   		INS	HME 	PGU
		 41  2   3   4   5   6   7   8   9   10  11  12  13  43  14        	DEL	END	PGD

																	  {   }
		 TAB   Q   W   E   R   T   Y   U   I   O   P   [   ]
		 15    16  17  18  19  20  21  22  23  24  25  26  27

																	:   "
		 CPS     A   S   D   F   G   H   J   K   L   ;   '       RET      			 UP
		 58      30  31  32  33  34  35  36  37  38  39  40      28

															<   >   ?
		 SHF       Z   X   C   V   B   N   M   ,   .   /         SHF         	LFT DWN RGT
		 42        44  45  46  47  48  49  50  51  52  53        54

		 CTL  ALT         SPACEBAR 				ALT  CTL
		 29	56				57



		map  ~   to  }
			  `       ]

		ALT to SLK

		F11  to p
				  _

		f12  menu

		pause/break to BRK

 */

unsigned char scan2bbc[128]=              // IBM      SCAN CODE            BBC
{
			0xAA,0x70,0x30,0x31,    			// .ESC12  	0,1,2,3
			0x11,0x12,0x13,0x34,             // 3456  	4,5,6,7
			0x24,0x15,0x26,0x27,             // 7890  	8,9,10,11
			0x17,0x18,0x59,	   	  	  		// -=DEL   	12,13,14

			0x60,0x10,0x21,0x22,	 	  	  		// TABqwe  	15,16,17,18				TABqwe
			0x33,0x23,0x44,0x35,	 	 	  		// rtyu   	19,20,21,22    		rtyu
			0x25,0x36,0x37,0x47,0x38,0x49,	// iop[]RET 23,24,25,26,27,28		iop@[RET (miss _)

			0x01,0x41,0x51,0x32,		  	 		// CTRLasd  29,30,31,32          CTRLasd
			0x43,0x53,0x54,0x45,		 	 		// fghj  	33,34,35,36          fghj
			0x46,0x56,0x57,0x48,0x58, 			// kl;'~   	37,38,39,40,41			kl+*]

		 	0x00,0x78,0x61,0x42,0x52,	  	 	// LSH\zxc 	42,43,44,45,46
			0x63,0x64,0x55,0x65,	  	 	  		// vbnm   	47,48,49,50
			0x66,0x67,0x68,0x00,0xAA, 	  		// <>?RSH.  51,52,53,54,55
			0x50,0x62,0x40,			  	  		// ALT,SPC,CAPS  56,57,58   		SHIFTLOCK,SPC,CAPs
			0x20,0x71, 	 				  	  		// f1,f2   	59,60          		f0,f1
			0x72,0x73,  	 			 	  		// f3,f4   	61,62
			0x14,0x74,      			  	  		// f5,f6   	63,64
			0x75,0x16,      			  	  		// f7,f8   	65,66
			0x76,0x77,0xAA,  			  	  		// f9,f10   67,68,69
			0xAA,                            //          		70
			0xAA,0x39,0xAA,0xAA,					//	hme upA pgu	min 	71,72,73,74
	   	0x19,0xaa,0x79,0xaa,					//	lft mid rgt plu	74,75,76,77
	   	0xAA,0x29,0xaa,			  			//	end dna pgd			78,79,80
	   	0xAA,0x69,								//	ins del ...			81,82,83
	   	0xAA,0xAA,								//				84,85
	   	0xAA,										//				86
			0x28,0xaa,						 		// f11,f12 	87,88 					--,BRK
			0xaa,0xaa,0xaa,0xaa,					//          89,90,91,92
			0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,		//		93-99
			0xaa,0xaa,0xaa,0xaa,0xaa,		 	//		100-104
			0xaa,0xaa,0xaa,0xaa,0xaa, 			//		105-109
		   0xaa,0xaa,0xaa,0xaa,0xaa, 			//		110-114
		   0xaa,0xaa,0xaa,0xaa,0xaa, 			//		115-119
			0xaa,0xaa,0xaa,0xaa,0xaa, 			//		120-124
			0xaa,0xaa,0xaa		 	  				//		120-127

};

char     *disc_name=0;
BeebWin  *mainWin;
/*******************************************************************************************


         MAIN


*******************************************************************************************/
void	main(int	argc,char *argv[])
{
   unsigned char  a;
   int            row,col;
   int            once=0;
   unsigned char  mask=0xff;
   char           *DiscString=getenv("BeebDiscDir");
   char           filename[128];
	double			LastCycles;
   int            i,j;
   char           key[128];
   unsigned char  lastcounter;
   int              SpeedTrigger=0;

   GetDOSMemory();
   install_keyboard_interrupt();
   InitSound();
	SetModeX();
	SetBBCPalette();

   while(1)
   {
/*******************************************************************************************


      FOR DISC MENU


*******************************************************************************************/
      parse_gamefile();

      if (DiscString)
         sprintf(filename,"%s//*.?sd",DiscString);
      else
         sprintf(filename,"*.?sd");

      disc_name=menu(filename);

      if (disc_name==0 && inkey(1))
      {
         setrez(03);
         printf("Goodbye from BeebemDOS V1.2 MHG %s\n",__DATE__);
         exit(1);
      }

      BeebMemInit();
      Init6502core();
      SysVIAReset();
      SoundInit();
      UserVIAReset();
      VideoInit();
      Disc8271_reset();          //loads disc required

//  	DumpRegs();

      mainWin=new BeebWin();

      if (menutype==2)
         load_game(cursor_pos);  //inserts text

      while(1)
      {
         insert();               //inserts commands into keyboard buffer
         a=LookKey();            //gets a key pressed
         a=a&mask;
         mask|=0xff;

         if (a==0xe1) mask=0;

         if (a & 0x80) key[a&0x7f]=0; else key[a]=1;

         if (a)
         {
            if (a & 0x80)
            {
               if(TranslateKey(a & 0x7f, &row, &col)>=0)
               {
                     BeebKeyUp(row, col);
               }


               if(a==0xC5 || a==0xc6)           //BRK key released - Must do a reset!
               {
                  if (key[CTRL])                //CTRL_BRK pressed - bigger reset
                  {
						  	BeebMemInit();
						  	Init6502core();
						  	SysVIAReset();
						  	UserVIAReset();
						  	VideoInit();
						  	Disc8271_reset();
                  }
                  else
                  {
                      Init6502core();
                      Disc8271_reset();
                  }
               }
            }
            else
            {

               if (key[F11])
                save_screen(&dummy[0]);


               if(TranslateKey(a,&row, &col)>=0)
               {
                  BeebKeyDown(row, col);
               }
            }
         }


         if (a==0x58)                     // f12 pressed - quit to menu
         {
               if (key[CTRL])                //CTRL_BRK pressed - bigger reset
                  {
                     key[CTRL]=0;
                     save_screen(&dummy[0]);
                  }
                  else
                  {
               ClearSound();
               break;
                  }
         }
         Exec6502Instruction();           // do 256 6502 instructions

#if LIMITSPEED
         if (SpeedTrigger<=TotalCycles)   //time to check if its running too fast
         {
            SpeedTrigger+=SPEEDGAP;
            if (soundon)
            {
               while(lastcounter==*soundflag)
               {
               }
               lastcounter=*soundflag;
            }
         }
#endif
      }
   }
 	setrez(3);
}
/*******************************************************************************************


      convert key from ibm scan code to bbc


*******************************************************************************************/
int TranslateKey(int index, int *row, int *col)
{
	unsigned int	vkey=scan2bbc[index & 127];

   if (vkey==0xaa) return(-1);

	col[0] = vkey&15;
	row[0] = (vkey>>4)&15;

	return(row[0]);
}
/*******************************************************************************************


      ERROR TRAPPER


*******************************************************************************************/
void  error(char *t1,char *t2)
{
	setrez(3);
	printf("ERROR: %s %s\n",t1,t2);
	exit(1);
}


