#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <string.h>

#include "z80emu.c" // bez toho nejni Z80reset
// #include "z80emu.h" // bez toho nejni zxout
#include "zxem.h"
#include "PMI80_rom.h"
#include "megaROM2.h"
//#include "ROM3.h"

#define Z80_SPH          12
#define Z80_SPL          13



static int touchpad_fd = -1; // touchpad input device
static int keypad_fd = -1; // keypad input device
static int printer_fd = -1; // printer output device
static int dsp_fd = -1;   // sound device, not finished yet

    int fbfd = 0;    // framebuffer  nastavení rozlišeí atd.
    struct fb_var_screeninfo vinfo;
    struct fb_fix_screeninfo finfo;
    long int screensize = 0;
    char *fbp = 0;
    char *framebuffer;
    int x = 0, y = 0;
    int seq, t;
    long int location = 0;
    long int framebuffer_pos;
   // 	unsigned short int 
      int red = 254<<11 | 0 | 0;// ostrá červená = svítíme
      int tma = 100 | 0 | 0 ; // tmavě modrá

unsigned char LEDcontrol;
unsigned char prevLEDcon;
unsigned char *memory;  // memory space including ROM, screenbuffer, etc.
unsigned char kbdlines[8];	// keyboard lines, as per http://www.breakintoprogram.co.uk/hardware/computers/zx-spectrum/keyboard

#include "img.h" // soubor s hexadecimálními daty obrázku klávesnice PMI


void HEXA1(int seq,int t)  //seq je pozice 0-9 a t je RGB color
{
//seg A1
	  for (y = 4; y < 11; y++)  { x = 319;  		
              	 location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) + ((seq*27)+y+vinfo.yoffset) * finfo.line_length;
                *((unsigned short int*)(fbp + location)) = t; }
          for (y = 3; y < 11; y++)  { x = 318; 
              	 location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) + ((seq*27)+y+vinfo.yoffset) * finfo.line_length;
                *((unsigned short int*)(fbp + location)) = t; }
          for (y = 4; y < 11; y++)  { x = 317; 
              	 location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) + ((seq*27)+y+vinfo.yoffset) * finfo.line_length;
                *((unsigned short int*)(fbp + location)) = t; }
}


void HEXA2(int seq,int t)  //seq je pozice 0-9 a t je RGB color
{
//seg A2
 
	  for (y = 13; y < 20; y++)  { x = 319;  		
              	 location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) + ((seq*27)+y+vinfo.yoffset) * finfo.line_length;
                *((unsigned short int*)(fbp + location)) = t; }
          for (y = 13; y < 21; y++)  { x = 318; 
              	 location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) + ((seq*27)+y+vinfo.yoffset) * finfo.line_length;
                *((unsigned short int*)(fbp + location)) = t; }
          for (y = 14; y < 20; y++)  { x = 317; 
              	 location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) + ((seq*27)+y+vinfo.yoffset) * finfo.line_length;
                *((unsigned short int*)(fbp + location)) = t; }
}

void HEXB(int seq,int t)  //seq je pozice 0-9 a t je RGB color
{
// seg B
	  for (x = 316; x > 293; x--)  { y = 21;  		
              	 location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) + ((seq*27)+y+vinfo.yoffset) * finfo.line_length;
                *((unsigned short int*)(fbp + location)) = t; }
	  for (x = 317; x > 292; x--)  { y = 22;  		
              	 location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) + ((seq*27)+y+vinfo.yoffset) * finfo.line_length;
                *((unsigned short int*)(fbp + location)) = t; }
	  for (x = 316; x > 292; x--)  { y = 23;  		
              	 location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) + ((seq*27)+y+vinfo.yoffset) * finfo.line_length;
                *((unsigned short int*)(fbp + location)) = t; }
 }
void HEXC(int seq,int t)  //seq je pozice 0-9 a t je RGB color
{               
// seg C
	  for (x = 289; x > 266; x--)  { y = 21;  		
              	 location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) + ((seq*27)+y+vinfo.yoffset) * finfo.line_length;
                *((unsigned short int*)(fbp + location)) = t; }
	  for (x = 290; x > 265; x--)  { y = 22;  		
              	 location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) + ((seq*27)+y+vinfo.yoffset) * finfo.line_length;
                *((unsigned short int*)(fbp + location)) = t; }
	  for (x = 290; x > 266; x--)  { y = 23;  		
              	 location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) + ((seq*27)+y+vinfo.yoffset) * finfo.line_length;
                *((unsigned short int*)(fbp + location)) = t; }
}

void HEXD1(int seq,int t)  //seq je pozice 0-9 a t je RGB color
{
//seg D1
	  for (y = 4; y < 10; y++)  { x = 265;  		
              	 location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) + ((seq*27)+y+vinfo.yoffset) * finfo.line_length;
                *((unsigned short int*)(fbp + location)) = t; }
          for (y = 3; y < 11; y++)  { x = 264; 
              	 location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) + ((seq*27)+y+vinfo.yoffset) * finfo.line_length;
                *((unsigned short int*)(fbp + location)) = t; }
          for (y = 4; y < 11; y++)  { x = 263; 
              	 location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) + ((seq*27)+y+vinfo.yoffset) * finfo.line_length;
                *((unsigned short int*)(fbp + location)) = t; }
                } 
void HEXD2(int seq,int t)  //seq je pozice 0-9 a t je RGB color
{
//seg D2 
	  for (y = 14; y < 20; y++)  { x = 265;  		
              	 location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) + ((seq*27)+y+vinfo.yoffset) * finfo.line_length;
                *((unsigned short int*)(fbp + location)) = t; }
          for (y = 13; y < 21; y++)  { x = 264; 
              	 location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) + ((seq*27)+y+vinfo.yoffset) * finfo.line_length;
                *((unsigned short int*)(fbp + location)) = t; }
          for (y = 13; y < 20; y++)  { x = 263; 
              	 location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) + ((seq*27)+y+vinfo.yoffset) * finfo.line_length;
                *((unsigned short int*)(fbp + location)) = t; }

}

void HEXE(int seq,int t)  //seq je pozice 0-9 a t je RGB color
{
// seg E
	  for (x = 290; x > 266; x--)  { y = 1;  		
              	 location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) + ((seq*27)+y+vinfo.yoffset) * finfo.line_length;
                *((unsigned short int*)(fbp + location)) = t; }
	  for (x = 290; x > 265; x--)  { y = 2;  		
              	 location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) + ((seq*27)+y+vinfo.yoffset) * finfo.line_length;
                *((unsigned short int*)(fbp + location)) = t; }
	  for (x = 289; x > 266; x--)  { y = 3;  		
              	 location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) + ((seq*27)+y+vinfo.yoffset) * finfo.line_length;
                *((unsigned short int*)(fbp + location)) = t; }
                }
void HEXF(int seq,int t)  //seq je pozice 0-9 a t je RGB color
{                
// seg F
	  for (x = 316; x > 292; x--)  { y = 1;  		
              	 location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) + ((seq*27)+y+vinfo.yoffset) * finfo.line_length;
                *((unsigned short int*)(fbp + location)) = t; }
	  for (x = 317; x > 292; x--)  { y = 2;  		
              	 location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) + ((seq*27)+y+vinfo.yoffset) * finfo.line_length;
                *((unsigned short int*)(fbp + location)) = t; }
	  for (x = 316; x > 293; x--)  { y = 3;  		
              	 location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) + ((seq*27)+y+vinfo.yoffset) * finfo.line_length;
                *((unsigned short int*)(fbp + location)) = t; }
}

void HEXG1(int seq,int t)  //seq je pozice 0-9 a t je RGB color
{ 
//seg G1
	  for (y = 5; y < 10; y++)  { x = 292;  		
              	 location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) + ((seq*27)+y+vinfo.yoffset) * finfo.line_length;
                *((unsigned short int*)(fbp + location)) = t; }
          for (y = 4; y < 11; y++)  { x = 291; 
              	 location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) + ((seq*27)+y+vinfo.yoffset) * finfo.line_length;
                *((unsigned short int*)(fbp + location)) = t; }
          for (y = 5; y < 10; y++)  { x = 290; 
              	 location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) + ((seq*27)+y+vinfo.yoffset) * finfo.line_length;
                *((unsigned short int*)(fbp + location)) = t; }
}
void HEXG2(int seq,int t)  //seq je pozice 0-9 a t je RGB color
{ 
//seg G2 
	  for (y = 14; y < 19; y++)  { x = 292;  		
              	 location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) + ((seq*27)+y+vinfo.yoffset) * finfo.line_length;
                *((unsigned short int*)(fbp + location)) = t; }
          for (y = 13; y < 20; y++)  { x = 291; 
              	 location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) + ((seq*27)+y+vinfo.yoffset) * finfo.line_length;
                *((unsigned short int*)(fbp + location)) = t; }
          for (y = 14; y < 19; y++)  { x = 290; 
              	 location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) + ((seq*27)+y+vinfo.yoffset) * finfo.line_length;
                *((unsigned short int*)(fbp + location)) = t; }
}

void HEXH(int seq,int t)  //seq je pozice 0-9 a t je RGB color
{                           
// seg H
	  for (x = 315; x > 312; x--)  { y = 5;  		
              	 location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) + ((seq*27)+y+vinfo.yoffset) * finfo.line_length;
                *((unsigned short int*)(fbp + location)) = t; }
	  for (x = 315; x > 303; x--)  { y = 6;  		
              	 location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) + ((seq*27)+y+vinfo.yoffset) * finfo.line_length;
                *((unsigned short int*)(fbp + location)) = t; }
	  for (x = 312; x > 297; x--)  { y = 7;  		
              	 location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) + ((seq*27)+y+vinfo.yoffset) * finfo.line_length;
                *((unsigned short int*)(fbp + location)) = t; }
          for (x = 305; x > 294; x--)  { y = 8;  		
              	 location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) + ((seq*27)+y+vinfo.yoffset) * finfo.line_length;
                *((unsigned short int*)(fbp + location)) = t; }
	  for (x = 297; x > 294; x--)  { y = 9;  		
              	 location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) + ((seq*27)+y+vinfo.yoffset) * finfo.line_length;
                *((unsigned short int*)(fbp + location)) = t; }      
}
void HEXI(int seq,int t)  //seq je pozice 0-9 a t je RGB color
{
// seg I
	  for (x = 316; x > 293; x--)  { y = 11;  		
              	 location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) + ((seq*27)+y+vinfo.yoffset) * finfo.line_length;
                *((unsigned short int*)(fbp + location)) = t; }
	  for (x = 317; x > 292; x--)  { y = 12;  		
              	 location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) + ((seq*27)+y+vinfo.yoffset) * finfo.line_length;
                *((unsigned short int*)(fbp + location)) = t; }
	  for (x = 316; x > 293; x--)  { y = 13;  		
              	 location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) + ((seq*27)+y+vinfo.yoffset) * finfo.line_length;
                *((unsigned short int*)(fbp + location)) = t; }
}
void HEXJ(int seq,int t)  //seq je pozice 0-9 a t je RGB color
{               
// seg J
	  for (x = 315; x > 312; x--)  { y = 19;  		
              	 location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) + ((seq*27)+y+vinfo.yoffset) * finfo.line_length;
                *((unsigned short int*)(fbp + location)) = t; }
	  for (x = 315; x > 303; x--)  { y = 18;  		
              	 location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) + ((seq*27)+y+vinfo.yoffset) * finfo.line_length;
                *((unsigned short int*)(fbp + location)) = t; }
	  for (x = 312; x > 297; x--)  { y = 17;  		
              	 location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) + ((seq*27)+y+vinfo.yoffset) * finfo.line_length;
                *((unsigned short int*)(fbp + location)) = t; }
          for (x = 305; x > 294; x--)  { y = 16;  		
              	 location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) + ((seq*27)+y+vinfo.yoffset) * finfo.line_length;
                *((unsigned short int*)(fbp + location)) = t; }
	  for (x = 297; x > 294; x--)  { y = 15;  		
              	 location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) + ((seq*27)+y+vinfo.yoffset) * finfo.line_length;
                *((unsigned short int*)(fbp + location)) = t; }      
}
void HEXK(int seq,int t)  //seq je pozice 0-9 a t je RGB color
{                
// seg K
	  for (x = 270; x > 267; x--)  { y = 19;  		
              	 location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) + ((seq*27)+y+vinfo.yoffset) * finfo.line_length;
                *((unsigned short int*)(fbp + location)) = t; }
	  for (x = 278; x > 267; x--)  { y = 18;  		
              	 location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) + ((seq*27)+y+vinfo.yoffset) * finfo.line_length;
                *((unsigned short int*)(fbp + location)) = t; }
	  for (x = 285; x > 270; x--)  { y = 17;  		
              	 location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) + ((seq*27)+y+vinfo.yoffset) * finfo.line_length;
                *((unsigned short int*)(fbp + location)) = t; }
          for (x = 288; x > 276; x--)  { y = 16;  		
              	 location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) + ((seq*27)+y+vinfo.yoffset) * finfo.line_length;
                *((unsigned short int*)(fbp + location)) = t; }
	  for (x = 288; x > 285; x--)  { y = 15;  		
              	 location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) + ((seq*27)+y+vinfo.yoffset) * finfo.line_length;
                *((unsigned short int*)(fbp + location)) = t; }  
}
void HEXL(int seq,int t)  //seq je pozice 0-9 a t je RGB color
{                
// seg L
	  for (x = 289; x > 266; x--)  { y = 11;  		
              	 location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) + ((seq*27)+y+vinfo.yoffset) * finfo.line_length;
                *((unsigned short int*)(fbp + location)) = t; }
	  for (x = 290; x > 265; x--)  { y = 12;  		
              	 location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) + ((seq*27)+y+vinfo.yoffset) * finfo.line_length;
                *((unsigned short int*)(fbp + location)) = t; }
	  for (x = 289; x > 266; x--)  { y = 13;  		
              	 location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) + ((seq*27)+y+vinfo.yoffset) * finfo.line_length;
                *((unsigned short int*)(fbp + location)) = t; }                    
}
void HEXM(int seq,int t)  //seq je pozice 0-9 a t je RGB color
{                
// seg M
	  for (x = 270; x > 267; x--)  { y = 5;  		
              	 location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) + ((seq*27)+y+vinfo.yoffset) * finfo.line_length;
                *((unsigned short int*)(fbp + location)) = t; }
	  for (x = 278; x > 267; x--)  { y = 6;  		
              	 location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) + ((seq*27)+y+vinfo.yoffset) * finfo.line_length;
                *((unsigned short int*)(fbp + location)) = t; }
	  for (x = 285; x > 270; x--)  { y = 7;  		
              	 location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) + ((seq*27)+y+vinfo.yoffset) * finfo.line_length;
                *((unsigned short int*)(fbp + location)) = t; }
          for (x = 288; x > 276; x--)  { y = 8;  		
              	 location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) + ((seq*27)+y+vinfo.yoffset) * finfo.line_length;
                *((unsigned short int*)(fbp + location)) = t; }
	  for (x = 288; x > 285; x--)  { y = 9;  		
              	 location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) + ((seq*27)+y+vinfo.yoffset) * finfo.line_length;
                *((unsigned short int*)(fbp + location)) = t; }  
}    


void display (int value, int seq )  // zobrazujeme na pozici seq obsah z value
{
      printf ("Voláme display X=%X val= %X\n", seq, value);

      if (~value & 0x40)   {HEXG1(seq,red); HEXG2(seq,red);}    
      if (~value & 0x20)   HEXF(seq,red);
      if (~value & 0x10)   HEXE(seq,red);
      if (~value & 0x08)   { HEXD1(seq,red); HEXD2(seq,red);}
      if (~value & 0x04)   HEXC(seq,red);
      if (~value & 0x02)   HEXB(seq,red);
      if (~value & 0x01)   { HEXA1(seq,red); HEXA2(seq,red);}
// kdyz nema sviti smazeme
      if (value & 0x40)   {HEXG1(seq,tma); HEXG2(seq,tma);}    
      if (value & 0x20)   HEXF(seq,tma);
      if (value & 0x10)   HEXE(seq,tma);
      if (value & 0x08)   { HEXD1(seq,tma); HEXD2(seq,tma);}
      if (value & 0x04)   HEXC(seq,tma);
      if (value & 0x02)   HEXB(seq,tma);
      if (value & 0x01)   { HEXA1(seq,tma); HEXA2(seq,tma);}
}

/*
 ZX OUT port
 
 this should be implemented for sound
*/
void
zxout (int port, int value)
{
  printf ("OUT %X %X\n", port, value);
  
  
switch (port & 0xFF) {
        /* Periferie PMI-80
         *   periferiemi se komunikovalo na adresách F8, F9, FA a FB 
         *   (klasická čtveřice registrů 8255 – PA, PB, PC, řídicí). 
         *   Displej používal budič a dekodér 1-z-9 typu MH1082, 
         *   připojený na port PC (=adresa FA), bity 0-3. 
         *   Tímto bitem se vybírala pozice na displeji. 
         *   Segmenty ovládal port PA (=adresa F8), 
         *   a to bity 0-6 (bit 7 nebyl zapojený, desetinná tečka nefungovala).
         *   PC4 5 6 slouží pro čtení klavesnice

         */    
    case 0xFA: //// 0xFA led control řídící bity 0-3  která pozice 0xF je poslední  a 7 je první a klavesnice sloupce
         prevLEDcon = LEDcontrol;
         LEDcontrol   = value & 0x0f; //B00001111;
        break;   
    case 0xF8: // 0xF8 led value - segmenty bity 0-6 - bacha jsou negované   PA-0xF8   a PB-0xFA (LEDcontrol)
         switch (LEDcontrol){           
               case 0x0F:  //první segmentofka 0xF
                 display ( value,0);
               break;
               case 0x0E:  //druhá segmentofka
                display ( value,1);
                break;
                case 0x0D:  //třetí segmentofka
                display ( value,2);
                break;
                case 0x0C:  //čtvrtá segmentofka
                 display ( value,3);
                break;
                case 0x0B:  //pátá segmentofka
                display ( value,4);
                break;
                case 0x0A:  //šestá segmentofka
                display ( value,5);
                break;
                case 0x09:  //sedmá segmentofka
                display ( value,6);
                break;
                case 0x08:  //osmá segmentofka
                display ( value,7);
                break;
                case 0x07:  //devátá segmentofka
                display ( value,8);
                break;
                                
               }
                  
             break;
        
          }

//**********************************************
}


/*
 Z80 in-port
*/
int
zxin (int port)
{
  int i, v;
  
  /*
    tehere is some kind of bug that prevents me from masking keystrokes
    if manic miner is reading multiple keylines at one time. this happens 
    at 0x8c5c, see https://skoolkid.github.io/manicminer/asm/8BDD.html
    so we force the last keyline with space to allow jumping
    
    this should be fixed for other games or if it becomes obvious that manic
    miner needs more keys than implemented now :)
  */


  if ((port & 0xFF) == 0xFE)
    {
      v = 0x1f;
      for (i = 0; i < 8; i++)
	if ((port & (1 << (i + 8))) == 0)
	  {
	    v &= kbdlines[i];

                return v;
	  }
      //return v;
    }
  printf ("IN %X\n", port);

  return 0;
}

/*
 This handles writes to low memory to allow screen redraw. All changes are
 stored in global memory[] buffer
*/
void
z80lowmemwrite (int addr, int val)
{
  // pokus o zápis do dolního kila ROM paměti (podívej do z80user.h) < 0x400
      printf ("Unhandled ROMwrite addr=%X val= %X\n", addr, val);
}
        
int _init()
{

    // Open the file for reading and writing
    fbfd = open("/dev/fb", O_RDWR);
    if (fbfd == -1) {
        perror("Error: cannot open framebuffer device");
        exit(1);
    }
    printf("The framebuffer device was opened successfully.\n");

    // Get fixed screen information
    if (ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo) == -1) {
        perror("Error reading fixed information");
        exit(2);
    }

    // Get variable screen information
    if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo) == -1) {
        perror("Error reading variable information");
        exit(3);
    }

   // printf("%dx%d, %dbpp\n", vinfo.xres, vinfo.yres, vinfo.bits_per_pixel);

    // Figure out the size of the screen in bytes
    screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;

    // Map the device to memory
    fbp = (char *)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fbfd, 0);
    if ((int)fbp == -1) {
        perror("Error: failed to map framebuffer device to memory");
        exit(4);
    }
   
        
    // Figure out where in memory to put the picure
    for (y = 00; y < 240; y++)
        for (x = 00; x < 260; x++) {	
            location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) +
                       (y+vinfo.yoffset) * finfo.line_length;
             { 
             //assume 16bpp
                int b = 64 - (y-100)/16; //100;
                int g = (x-100)/6;     // A little green
                int r = x; //31-(y-100)/16;    // A lot of red
                int picturepos = ((260-x)*240+y);              // 6 0 0 
                unsigned short int t = img_data[picturepos*3] << 6 | img_data[picturepos*3+1] | img_data[picturepos*3+2] ; // r<<11 | g << 5 | b;
                *((unsigned short int*)(fbp + location)) = t;
            }
        }
       
// prostor pro display je y:0-240 a x:260-320
    // celý display zhasneme
        t = tma;
   	for (int seq = 0; seq < 9; seq++) {

	HEXA1 (seq,t);
	HEXA2 (seq,t);
	HEXB (seq,t);
	HEXC (seq,t);
        HEXD1 (seq,t);
	HEXD2 (seq,t);
	HEXE (seq,t);
	HEXF (seq,t);
	HEXG1 (seq,t);
	HEXG2 (seq,t);
	HEXH (seq,t);
	HEXI (seq,t);
        HEXJ (seq,t);
	HEXK (seq,t);
	HEXL (seq,t);
	HEXM (seq,t);
                                
}


  
     
         // emulovat 
         
  char *romfilename;
  int fd;
  int cycles;
  int i;
  struct stat sb;

  Z80_STATE state;

  memory = (unsigned char *) malloc (0x10000);
  memset (memory, 0, 0x10000);
  memcpy (&memory[0x0], &ROM[0x0], 1024); //zkopirujeme PMI-ROM do RAM
  memcpy (&memory[0x0400], &ROM2[0x1400], 1024); //zkopirujeme část megaROM2.h do RAM na 0x0400
/*  &ROM2[0x000] Cosmos a pong
    &ROM2[0x100] "br-Stop"
    &ROM2[0x1000] "pmi -80" A DALSI EFEKT / intension
    &ROM2[0x1400] "Spool"
*/
  for (i = 0; i < 8; i++)
    kbdlines[i] = 0x1f;


  

  Z80Reset (&state);

  state.pc = 0x0000;


  cycles = 0;

  while (1)
    {
      cycles += Z80Emulate (&state, 200 /*cycles */ , NULL);
 //         for (int o = 0; o < (10000); o++) ; //zpomlait
     /*if (cycles > 1024*10)
	{
	  handle_x (); // handle keyboard (keypad)
	  Z80Interrupt (&state, 0, NULL);
	  cycles = 0;
	}
   */
      if (cycles > 3024000 * 2)
	{
	  // Z80Interrupt (&state, 0, NULL);
	  cycles = 0;
	  printf ("smycka dobehla\n");
	   for (x = 0; x < 320; x++) // CLS
	   for (y = 0; y < 240; y++)  {  		
              	 location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) + ((seq*27)+y+vinfo.yoffset) * finfo.line_length;
                *((unsigned short int*)(fbp + location)) = 0 | 0 | 0; }

          munmap(fbp, screensize);
          sleep (1);
           exit (1);
	}
      }

  return 0;
         // Uzavřít framebuffer
              

    close(fbfd);
    return 0;
}