diff src/gb/GB.cpp @ 33:44974c3e093b

found source of problem for video recording
author Robert McIntyre <rlm@mit.edu>
date Mon, 05 Mar 2012 01:25:11 -0600
parents f9f4f1b99eed
children 3e36553d0cbf
line wrap: on
line diff
     1.1 --- a/src/gb/GB.cpp	Sun Mar 04 22:44:42 2012 -0600
     1.2 +++ b/src/gb/GB.cpp	Mon Mar 05 01:25:11 2012 -0600
     1.3 @@ -163,361 +163,361 @@
     1.4  static bool pauseAfterFrameAdvance = false;
     1.5  
     1.6  int32 gbRomSizes[] = { 0x00008000, // 32K
     1.7 -	                   0x00010000, // 64K
     1.8 -	                   0x00020000, // 128K
     1.9 -	                   0x00040000, // 256K
    1.10 -	                   0x00080000, // 512K
    1.11 -	                   0x00100000, // 1024K
    1.12 -	                   0x00200000, // 2048K
    1.13 -	                   0x00400000, // 4096K
    1.14 -	                   0x00800000 // 8192K
    1.15 +		       0x00010000, // 64K
    1.16 +		       0x00020000, // 128K
    1.17 +		       0x00040000, // 256K
    1.18 +		       0x00080000, // 512K
    1.19 +		       0x00100000, // 1024K
    1.20 +		       0x00200000, // 2048K
    1.21 +		       0x00400000, // 4096K
    1.22 +		       0x00800000 // 8192K
    1.23  };
    1.24  int32 gbRomSizesMasks[] = { 0x00007fff,
    1.25 -	                        0x0000ffff,
    1.26 -	                        0x0001ffff,
    1.27 -	                        0x0003ffff,
    1.28 -	                        0x0007ffff,
    1.29 -	                        0x000fffff,
    1.30 -	                        0x001fffff,
    1.31 -	                        0x003fffff,
    1.32 -	                        0x007fffff };
    1.33 +			    0x0000ffff,
    1.34 +			    0x0001ffff,
    1.35 +			    0x0003ffff,
    1.36 +			    0x0007ffff,
    1.37 +			    0x000fffff,
    1.38 +			    0x001fffff,
    1.39 +			    0x003fffff,
    1.40 +			    0x007fffff };
    1.41  
    1.42  int32 gbRamSizes[6] = { 0x00000000, // 0K
    1.43 -	                    0x00000800, // 2K
    1.44 -	                    0x00002000, // 8K
    1.45 -	                    0x00008000, // 32K
    1.46 -	                    0x00020000, // 128K
    1.47 -	                    0x00010000 // 64K
    1.48 +			0x00000800, // 2K
    1.49 +			0x00002000, // 8K
    1.50 +			0x00008000, // 32K
    1.51 +			0x00020000, // 128K
    1.52 +			0x00010000 // 64K
    1.53  };
    1.54  
    1.55  int32 gbRamSizesMasks[6] = { 0x00000000,
    1.56 -	                         0x000007ff,
    1.57 -	                         0x00001fff,
    1.58 -	                         0x00007fff,
    1.59 -	                         0x0001ffff,
    1.60 -	                         0x0000ffff };
    1.61 +			     0x000007ff,
    1.62 +			     0x00001fff,
    1.63 +			     0x00007fff,
    1.64 +			     0x0001ffff,
    1.65 +			     0x0000ffff };
    1.66  
    1.67  int32 gbCycles[] =
    1.68 -{
    1.69 -//  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
    1.70 -	1, 3, 2, 2, 1, 1, 2, 1, 5, 2, 2, 2, 1, 1, 2, 1,  // 0
    1.71 -	1, 3, 2, 2, 1, 1, 2, 1, 3, 2, 2, 2, 1, 1, 2, 1,  // 1
    1.72 -	2, 3, 2, 2, 1, 1, 2, 1, 2, 2, 2, 2, 1, 1, 2, 1,  // 2
    1.73 -	2, 3, 2, 2, 3, 3, 3, 1, 2, 2, 2, 2, 1, 1, 2, 1,  // 3
    1.74 -	1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1,  // 4
    1.75 -	1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1,  // 5
    1.76 -	1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1,  // 6
    1.77 -	2, 2, 2, 2, 2, 2, 1, 2, 1, 1, 1, 1, 1, 1, 2, 1,  // 7
    1.78 -	1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1,  // 8
    1.79 -	1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1,  // 9
    1.80 -	1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1,  // a
    1.81 -	1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1,  // b
    1.82 -	2, 3, 3, 4, 3, 4, 2, 4, 2, 4, 3, 2, 3, 6, 2, 4,  // c
    1.83 -	2, 3, 3, 0, 3, 4, 2, 4, 2, 4, 3, 0, 3, 0, 2, 4,  // d
    1.84 -	3, 3, 2, 0, 0, 4, 2, 4, 4, 1, 4, 0, 0, 0, 2, 4,  // e
    1.85 -	3, 3, 2, 1, 0, 4, 2, 4, 3, 2, 4, 1, 0, 0, 2, 4   // f
    1.86 -};
    1.87 +  {
    1.88 +    //  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
    1.89 +    1, 3, 2, 2, 1, 1, 2, 1, 5, 2, 2, 2, 1, 1, 2, 1,  // 0
    1.90 +    1, 3, 2, 2, 1, 1, 2, 1, 3, 2, 2, 2, 1, 1, 2, 1,  // 1
    1.91 +    2, 3, 2, 2, 1, 1, 2, 1, 2, 2, 2, 2, 1, 1, 2, 1,  // 2
    1.92 +    2, 3, 2, 2, 3, 3, 3, 1, 2, 2, 2, 2, 1, 1, 2, 1,  // 3
    1.93 +    1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1,  // 4
    1.94 +    1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1,  // 5
    1.95 +    1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1,  // 6
    1.96 +    2, 2, 2, 2, 2, 2, 1, 2, 1, 1, 1, 1, 1, 1, 2, 1,  // 7
    1.97 +    1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1,  // 8
    1.98 +    1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1,  // 9
    1.99 +    1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1,  // a
   1.100 +    1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1,  // b
   1.101 +    2, 3, 3, 4, 3, 4, 2, 4, 2, 4, 3, 2, 3, 6, 2, 4,  // c
   1.102 +    2, 3, 3, 0, 3, 4, 2, 4, 2, 4, 3, 0, 3, 0, 2, 4,  // d
   1.103 +    3, 3, 2, 0, 0, 4, 2, 4, 4, 1, 4, 0, 0, 0, 2, 4,  // e
   1.104 +    3, 3, 2, 1, 0, 4, 2, 4, 3, 2, 4, 1, 0, 0, 2, 4   // f
   1.105 +  };
   1.106  
   1.107  int32 gbCyclesCB[] =
   1.108 -{
   1.109 -//  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
   1.110 -	2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2,  // 0
   1.111 -	2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2,  // 1
   1.112 -	2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2,  // 2
   1.113 -	2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2,  // 3
   1.114 -	2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2,  // 4
   1.115 -	2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2,  // 5
   1.116 -	2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2,  // 6
   1.117 -	2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2,  // 7
   1.118 -	2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2,  // 8
   1.119 -	2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2,  // 9
   1.120 -	2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2,  // a
   1.121 -	2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2,  // b
   1.122 -	2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2,  // c
   1.123 -	2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2,  // d
   1.124 -	2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2,  // e
   1.125 -	2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2   // f
   1.126 -};
   1.127 +  {
   1.128 +    //  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
   1.129 +    2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2,  // 0
   1.130 +    2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2,  // 1
   1.131 +    2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2,  // 2
   1.132 +    2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 4, 2,  // 3
   1.133 +    2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2,  // 4
   1.134 +    2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2,  // 5
   1.135 +    2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2,  // 6
   1.136 +    2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2,  // 7
   1.137 +    2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2,  // 8
   1.138 +    2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2,  // 9
   1.139 +    2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2,  // a
   1.140 +    2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2,  // b
   1.141 +    2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2,  // c
   1.142 +    2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2,  // d
   1.143 +    2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2,  // e
   1.144 +    2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 3, 2   // f
   1.145 +  };
   1.146  
   1.147  u16 DAATable[] =
   1.148 -{
   1.149 -	0x0080, 0x0100, 0x0200, 0x0300, 0x0400, 0x0500, 0x0600, 0x0700,
   1.150 -	0x0800, 0x0900, 0x1020, 0x1120, 0x1220, 0x1320, 0x1420, 0x1520,
   1.151 -	0x1000, 0x1100, 0x1200, 0x1300, 0x1400, 0x1500, 0x1600, 0x1700,
   1.152 -	0x1800, 0x1900, 0x2020, 0x2120, 0x2220, 0x2320, 0x2420, 0x2520,
   1.153 -	0x2000, 0x2100, 0x2200, 0x2300, 0x2400, 0x2500, 0x2600, 0x2700,
   1.154 -	0x2800, 0x2900, 0x3020, 0x3120, 0x3220, 0x3320, 0x3420, 0x3520,
   1.155 -	0x3000, 0x3100, 0x3200, 0x3300, 0x3400, 0x3500, 0x3600, 0x3700,
   1.156 -	0x3800, 0x3900, 0x4020, 0x4120, 0x4220, 0x4320, 0x4420, 0x4520,
   1.157 -	0x4000, 0x4100, 0x4200, 0x4300, 0x4400, 0x4500, 0x4600, 0x4700,
   1.158 -	0x4800, 0x4900, 0x5020, 0x5120, 0x5220, 0x5320, 0x5420, 0x5520,
   1.159 -	0x5000, 0x5100, 0x5200, 0x5300, 0x5400, 0x5500, 0x5600, 0x5700,
   1.160 -	0x5800, 0x5900, 0x6020, 0x6120, 0x6220, 0x6320, 0x6420, 0x6520,
   1.161 -	0x6000, 0x6100, 0x6200, 0x6300, 0x6400, 0x6500, 0x6600, 0x6700,
   1.162 -	0x6800, 0x6900, 0x7020, 0x7120, 0x7220, 0x7320, 0x7420, 0x7520,
   1.163 -	0x7000, 0x7100, 0x7200, 0x7300, 0x7400, 0x7500, 0x7600, 0x7700,
   1.164 -	0x7800, 0x7900, 0x8020, 0x8120, 0x8220, 0x8320, 0x8420, 0x8520,
   1.165 -	0x8000, 0x8100, 0x8200, 0x8300, 0x8400, 0x8500, 0x8600, 0x8700,
   1.166 -	0x8800, 0x8900, 0x9020, 0x9120, 0x9220, 0x9320, 0x9420, 0x9520,
   1.167 -	0x9000, 0x9100, 0x9200, 0x9300, 0x9400, 0x9500, 0x9600, 0x9700,
   1.168 -	0x9800, 0x9900, 0x00B0, 0x0130, 0x0230, 0x0330, 0x0430, 0x0530,
   1.169 -	0x0090, 0x0110, 0x0210, 0x0310, 0x0410, 0x0510, 0x0610, 0x0710,
   1.170 -	0x0810, 0x0910, 0x1030, 0x1130, 0x1230, 0x1330, 0x1430, 0x1530,
   1.171 -	0x1010, 0x1110, 0x1210, 0x1310, 0x1410, 0x1510, 0x1610, 0x1710,
   1.172 -	0x1810, 0x1910, 0x2030, 0x2130, 0x2230, 0x2330, 0x2430, 0x2530,
   1.173 -	0x2010, 0x2110, 0x2210, 0x2310, 0x2410, 0x2510, 0x2610, 0x2710,
   1.174 -	0x2810, 0x2910, 0x3030, 0x3130, 0x3230, 0x3330, 0x3430, 0x3530,
   1.175 -	0x3010, 0x3110, 0x3210, 0x3310, 0x3410, 0x3510, 0x3610, 0x3710,
   1.176 -	0x3810, 0x3910, 0x4030, 0x4130, 0x4230, 0x4330, 0x4430, 0x4530,
   1.177 -	0x4010, 0x4110, 0x4210, 0x4310, 0x4410, 0x4510, 0x4610, 0x4710,
   1.178 -	0x4810, 0x4910, 0x5030, 0x5130, 0x5230, 0x5330, 0x5430, 0x5530,
   1.179 -	0x5010, 0x5110, 0x5210, 0x5310, 0x5410, 0x5510, 0x5610, 0x5710,
   1.180 -	0x5810, 0x5910, 0x6030, 0x6130, 0x6230, 0x6330, 0x6430, 0x6530,
   1.181 -	0x6010, 0x6110, 0x6210, 0x6310, 0x6410, 0x6510, 0x6610, 0x6710,
   1.182 -	0x6810, 0x6910, 0x7030, 0x7130, 0x7230, 0x7330, 0x7430, 0x7530,
   1.183 -	0x7010, 0x7110, 0x7210, 0x7310, 0x7410, 0x7510, 0x7610, 0x7710,
   1.184 -	0x7810, 0x7910, 0x8030, 0x8130, 0x8230, 0x8330, 0x8430, 0x8530,
   1.185 -	0x8010, 0x8110, 0x8210, 0x8310, 0x8410, 0x8510, 0x8610, 0x8710,
   1.186 -	0x8810, 0x8910, 0x9030, 0x9130, 0x9230, 0x9330, 0x9430, 0x9530,
   1.187 -	0x9010, 0x9110, 0x9210, 0x9310, 0x9410, 0x9510, 0x9610, 0x9710,
   1.188 -	0x9810, 0x9910, 0xA030, 0xA130, 0xA230, 0xA330, 0xA430, 0xA530,
   1.189 -	0xA010, 0xA110, 0xA210, 0xA310, 0xA410, 0xA510, 0xA610, 0xA710,
   1.190 -	0xA810, 0xA910, 0xB030, 0xB130, 0xB230, 0xB330, 0xB430, 0xB530,
   1.191 -	0xB010, 0xB110, 0xB210, 0xB310, 0xB410, 0xB510, 0xB610, 0xB710,
   1.192 -	0xB810, 0xB910, 0xC030, 0xC130, 0xC230, 0xC330, 0xC430, 0xC530,
   1.193 -	0xC010, 0xC110, 0xC210, 0xC310, 0xC410, 0xC510, 0xC610, 0xC710,
   1.194 -	0xC810, 0xC910, 0xD030, 0xD130, 0xD230, 0xD330, 0xD430, 0xD530,
   1.195 -	0xD010, 0xD110, 0xD210, 0xD310, 0xD410, 0xD510, 0xD610, 0xD710,
   1.196 -	0xD810, 0xD910, 0xE030, 0xE130, 0xE230, 0xE330, 0xE430, 0xE530,
   1.197 -	0xE010, 0xE110, 0xE210, 0xE310, 0xE410, 0xE510, 0xE610, 0xE710,
   1.198 -	0xE810, 0xE910, 0xF030, 0xF130, 0xF230, 0xF330, 0xF430, 0xF530,
   1.199 -	0xF010, 0xF110, 0xF210, 0xF310, 0xF410, 0xF510, 0xF610, 0xF710,
   1.200 -	0xF810, 0xF910, 0x00B0, 0x0130, 0x0230, 0x0330, 0x0430, 0x0530,
   1.201 -	0x0090, 0x0110, 0x0210, 0x0310, 0x0410, 0x0510, 0x0610, 0x0710,
   1.202 -	0x0810, 0x0910, 0x1030, 0x1130, 0x1230, 0x1330, 0x1430, 0x1530,
   1.203 -	0x1010, 0x1110, 0x1210, 0x1310, 0x1410, 0x1510, 0x1610, 0x1710,
   1.204 -	0x1810, 0x1910, 0x2030, 0x2130, 0x2230, 0x2330, 0x2430, 0x2530,
   1.205 -	0x2010, 0x2110, 0x2210, 0x2310, 0x2410, 0x2510, 0x2610, 0x2710,
   1.206 -	0x2810, 0x2910, 0x3030, 0x3130, 0x3230, 0x3330, 0x3430, 0x3530,
   1.207 -	0x3010, 0x3110, 0x3210, 0x3310, 0x3410, 0x3510, 0x3610, 0x3710,
   1.208 -	0x3810, 0x3910, 0x4030, 0x4130, 0x4230, 0x4330, 0x4430, 0x4530,
   1.209 -	0x4010, 0x4110, 0x4210, 0x4310, 0x4410, 0x4510, 0x4610, 0x4710,
   1.210 -	0x4810, 0x4910, 0x5030, 0x5130, 0x5230, 0x5330, 0x5430, 0x5530,
   1.211 -	0x5010, 0x5110, 0x5210, 0x5310, 0x5410, 0x5510, 0x5610, 0x5710,
   1.212 -	0x5810, 0x5910, 0x6030, 0x6130, 0x6230, 0x6330, 0x6430, 0x6530,
   1.213 -	0x0600, 0x0700, 0x0800, 0x0900, 0x0A00, 0x0B00, 0x0C00, 0x0D00,
   1.214 -	0x0E00, 0x0F00, 0x1020, 0x1120, 0x1220, 0x1320, 0x1420, 0x1520,
   1.215 -	0x1600, 0x1700, 0x1800, 0x1900, 0x1A00, 0x1B00, 0x1C00, 0x1D00,
   1.216 -	0x1E00, 0x1F00, 0x2020, 0x2120, 0x2220, 0x2320, 0x2420, 0x2520,
   1.217 -	0x2600, 0x2700, 0x2800, 0x2900, 0x2A00, 0x2B00, 0x2C00, 0x2D00,
   1.218 -	0x2E00, 0x2F00, 0x3020, 0x3120, 0x3220, 0x3320, 0x3420, 0x3520,
   1.219 -	0x3600, 0x3700, 0x3800, 0x3900, 0x3A00, 0x3B00, 0x3C00, 0x3D00,
   1.220 -	0x3E00, 0x3F00, 0x4020, 0x4120, 0x4220, 0x4320, 0x4420, 0x4520,
   1.221 -	0x4600, 0x4700, 0x4800, 0x4900, 0x4A00, 0x4B00, 0x4C00, 0x4D00,
   1.222 -	0x4E00, 0x4F00, 0x5020, 0x5120, 0x5220, 0x5320, 0x5420, 0x5520,
   1.223 -	0x5600, 0x5700, 0x5800, 0x5900, 0x5A00, 0x5B00, 0x5C00, 0x5D00,
   1.224 -	0x5E00, 0x5F00, 0x6020, 0x6120, 0x6220, 0x6320, 0x6420, 0x6520,
   1.225 -	0x6600, 0x6700, 0x6800, 0x6900, 0x6A00, 0x6B00, 0x6C00, 0x6D00,
   1.226 -	0x6E00, 0x6F00, 0x7020, 0x7120, 0x7220, 0x7320, 0x7420, 0x7520,
   1.227 -	0x7600, 0x7700, 0x7800, 0x7900, 0x7A00, 0x7B00, 0x7C00, 0x7D00,
   1.228 -	0x7E00, 0x7F00, 0x8020, 0x8120, 0x8220, 0x8320, 0x8420, 0x8520,
   1.229 -	0x8600, 0x8700, 0x8800, 0x8900, 0x8A00, 0x8B00, 0x8C00, 0x8D00,
   1.230 -	0x8E00, 0x8F00, 0x9020, 0x9120, 0x9220, 0x9320, 0x9420, 0x9520,
   1.231 -	0x9600, 0x9700, 0x9800, 0x9900, 0x9A00, 0x9B00, 0x9C00, 0x9D00,
   1.232 -	0x9E00, 0x9F00, 0x00B0, 0x0130, 0x0230, 0x0330, 0x0430, 0x0530,
   1.233 -	0x0610, 0x0710, 0x0810, 0x0910, 0x0A10, 0x0B10, 0x0C10, 0x0D10,
   1.234 -	0x0E10, 0x0F10, 0x1030, 0x1130, 0x1230, 0x1330, 0x1430, 0x1530,
   1.235 -	0x1610, 0x1710, 0x1810, 0x1910, 0x1A10, 0x1B10, 0x1C10, 0x1D10,
   1.236 -	0x1E10, 0x1F10, 0x2030, 0x2130, 0x2230, 0x2330, 0x2430, 0x2530,
   1.237 -	0x2610, 0x2710, 0x2810, 0x2910, 0x2A10, 0x2B10, 0x2C10, 0x2D10,
   1.238 -	0x2E10, 0x2F10, 0x3030, 0x3130, 0x3230, 0x3330, 0x3430, 0x3530,
   1.239 -	0x3610, 0x3710, 0x3810, 0x3910, 0x3A10, 0x3B10, 0x3C10, 0x3D10,
   1.240 -	0x3E10, 0x3F10, 0x4030, 0x4130, 0x4230, 0x4330, 0x4430, 0x4530,
   1.241 -	0x4610, 0x4710, 0x4810, 0x4910, 0x4A10, 0x4B10, 0x4C10, 0x4D10,
   1.242 -	0x4E10, 0x4F10, 0x5030, 0x5130, 0x5230, 0x5330, 0x5430, 0x5530,
   1.243 -	0x5610, 0x5710, 0x5810, 0x5910, 0x5A10, 0x5B10, 0x5C10, 0x5D10,
   1.244 -	0x5E10, 0x5F10, 0x6030, 0x6130, 0x6230, 0x6330, 0x6430, 0x6530,
   1.245 -	0x6610, 0x6710, 0x6810, 0x6910, 0x6A10, 0x6B10, 0x6C10, 0x6D10,
   1.246 -	0x6E10, 0x6F10, 0x7030, 0x7130, 0x7230, 0x7330, 0x7430, 0x7530,
   1.247 -	0x7610, 0x7710, 0x7810, 0x7910, 0x7A10, 0x7B10, 0x7C10, 0x7D10,
   1.248 -	0x7E10, 0x7F10, 0x8030, 0x8130, 0x8230, 0x8330, 0x8430, 0x8530,
   1.249 -	0x8610, 0x8710, 0x8810, 0x8910, 0x8A10, 0x8B10, 0x8C10, 0x8D10,
   1.250 -	0x8E10, 0x8F10, 0x9030, 0x9130, 0x9230, 0x9330, 0x9430, 0x9530,
   1.251 -	0x9610, 0x9710, 0x9810, 0x9910, 0x9A10, 0x9B10, 0x9C10, 0x9D10,
   1.252 -	0x9E10, 0x9F10, 0xA030, 0xA130, 0xA230, 0xA330, 0xA430, 0xA530,
   1.253 -	0xA610, 0xA710, 0xA810, 0xA910, 0xAA10, 0xAB10, 0xAC10, 0xAD10,
   1.254 -	0xAE10, 0xAF10, 0xB030, 0xB130, 0xB230, 0xB330, 0xB430, 0xB530,
   1.255 -	0xB610, 0xB710, 0xB810, 0xB910, 0xBA10, 0xBB10, 0xBC10, 0xBD10,
   1.256 -	0xBE10, 0xBF10, 0xC030, 0xC130, 0xC230, 0xC330, 0xC430, 0xC530,
   1.257 -	0xC610, 0xC710, 0xC810, 0xC910, 0xCA10, 0xCB10, 0xCC10, 0xCD10,
   1.258 -	0xCE10, 0xCF10, 0xD030, 0xD130, 0xD230, 0xD330, 0xD430, 0xD530,
   1.259 -	0xD610, 0xD710, 0xD810, 0xD910, 0xDA10, 0xDB10, 0xDC10, 0xDD10,
   1.260 -	0xDE10, 0xDF10, 0xE030, 0xE130, 0xE230, 0xE330, 0xE430, 0xE530,
   1.261 -	0xE610, 0xE710, 0xE810, 0xE910, 0xEA10, 0xEB10, 0xEC10, 0xED10,
   1.262 -	0xEE10, 0xEF10, 0xF030, 0xF130, 0xF230, 0xF330, 0xF430, 0xF530,
   1.263 -	0xF610, 0xF710, 0xF810, 0xF910, 0xFA10, 0xFB10, 0xFC10, 0xFD10,
   1.264 -	0xFE10, 0xFF10, 0x00B0, 0x0130, 0x0230, 0x0330, 0x0430, 0x0530,
   1.265 -	0x0610, 0x0710, 0x0810, 0x0910, 0x0A10, 0x0B10, 0x0C10, 0x0D10,
   1.266 -	0x0E10, 0x0F10, 0x1030, 0x1130, 0x1230, 0x1330, 0x1430, 0x1530,
   1.267 -	0x1610, 0x1710, 0x1810, 0x1910, 0x1A10, 0x1B10, 0x1C10, 0x1D10,
   1.268 -	0x1E10, 0x1F10, 0x2030, 0x2130, 0x2230, 0x2330, 0x2430, 0x2530,
   1.269 -	0x2610, 0x2710, 0x2810, 0x2910, 0x2A10, 0x2B10, 0x2C10, 0x2D10,
   1.270 -	0x2E10, 0x2F10, 0x3030, 0x3130, 0x3230, 0x3330, 0x3430, 0x3530,
   1.271 -	0x3610, 0x3710, 0x3810, 0x3910, 0x3A10, 0x3B10, 0x3C10, 0x3D10,
   1.272 -	0x3E10, 0x3F10, 0x4030, 0x4130, 0x4230, 0x4330, 0x4430, 0x4530,
   1.273 -	0x4610, 0x4710, 0x4810, 0x4910, 0x4A10, 0x4B10, 0x4C10, 0x4D10,
   1.274 -	0x4E10, 0x4F10, 0x5030, 0x5130, 0x5230, 0x5330, 0x5430, 0x5530,
   1.275 -	0x5610, 0x5710, 0x5810, 0x5910, 0x5A10, 0x5B10, 0x5C10, 0x5D10,
   1.276 -	0x5E10, 0x5F10, 0x6030, 0x6130, 0x6230, 0x6330, 0x6430, 0x6530,
   1.277 -	0x00C0, 0x0140, 0x0240, 0x0340, 0x0440, 0x0540, 0x0640, 0x0740,
   1.278 -	0x0840, 0x0940, 0x0440, 0x0540, 0x0640, 0x0740, 0x0840, 0x0940,
   1.279 -	0x1040, 0x1140, 0x1240, 0x1340, 0x1440, 0x1540, 0x1640, 0x1740,
   1.280 -	0x1840, 0x1940, 0x1440, 0x1540, 0x1640, 0x1740, 0x1840, 0x1940,
   1.281 -	0x2040, 0x2140, 0x2240, 0x2340, 0x2440, 0x2540, 0x2640, 0x2740,
   1.282 -	0x2840, 0x2940, 0x2440, 0x2540, 0x2640, 0x2740, 0x2840, 0x2940,
   1.283 -	0x3040, 0x3140, 0x3240, 0x3340, 0x3440, 0x3540, 0x3640, 0x3740,
   1.284 -	0x3840, 0x3940, 0x3440, 0x3540, 0x3640, 0x3740, 0x3840, 0x3940,
   1.285 -	0x4040, 0x4140, 0x4240, 0x4340, 0x4440, 0x4540, 0x4640, 0x4740,
   1.286 -	0x4840, 0x4940, 0x4440, 0x4540, 0x4640, 0x4740, 0x4840, 0x4940,
   1.287 -	0x5040, 0x5140, 0x5240, 0x5340, 0x5440, 0x5540, 0x5640, 0x5740,
   1.288 -	0x5840, 0x5940, 0x5440, 0x5540, 0x5640, 0x5740, 0x5840, 0x5940,
   1.289 -	0x6040, 0x6140, 0x6240, 0x6340, 0x6440, 0x6540, 0x6640, 0x6740,
   1.290 -	0x6840, 0x6940, 0x6440, 0x6540, 0x6640, 0x6740, 0x6840, 0x6940,
   1.291 -	0x7040, 0x7140, 0x7240, 0x7340, 0x7440, 0x7540, 0x7640, 0x7740,
   1.292 -	0x7840, 0x7940, 0x7440, 0x7540, 0x7640, 0x7740, 0x7840, 0x7940,
   1.293 -	0x8040, 0x8140, 0x8240, 0x8340, 0x8440, 0x8540, 0x8640, 0x8740,
   1.294 -	0x8840, 0x8940, 0x8440, 0x8540, 0x8640, 0x8740, 0x8840, 0x8940,
   1.295 -	0x9040, 0x9140, 0x9240, 0x9340, 0x9440, 0x9540, 0x9640, 0x9740,
   1.296 -	0x9840, 0x9940, 0x3450, 0x3550, 0x3650, 0x3750, 0x3850, 0x3950,
   1.297 -	0x4050, 0x4150, 0x4250, 0x4350, 0x4450, 0x4550, 0x4650, 0x4750,
   1.298 -	0x4850, 0x4950, 0x4450, 0x4550, 0x4650, 0x4750, 0x4850, 0x4950,
   1.299 -	0x5050, 0x5150, 0x5250, 0x5350, 0x5450, 0x5550, 0x5650, 0x5750,
   1.300 -	0x5850, 0x5950, 0x5450, 0x5550, 0x5650, 0x5750, 0x5850, 0x5950,
   1.301 -	0x6050, 0x6150, 0x6250, 0x6350, 0x6450, 0x6550, 0x6650, 0x6750,
   1.302 -	0x6850, 0x6950, 0x6450, 0x6550, 0x6650, 0x6750, 0x6850, 0x6950,
   1.303 -	0x7050, 0x7150, 0x7250, 0x7350, 0x7450, 0x7550, 0x7650, 0x7750,
   1.304 -	0x7850, 0x7950, 0x7450, 0x7550, 0x7650, 0x7750, 0x7850, 0x7950,
   1.305 -	0x8050, 0x8150, 0x8250, 0x8350, 0x8450, 0x8550, 0x8650, 0x8750,
   1.306 -	0x8850, 0x8950, 0x8450, 0x8550, 0x8650, 0x8750, 0x8850, 0x8950,
   1.307 -	0x9050, 0x9150, 0x9250, 0x9350, 0x9450, 0x9550, 0x9650, 0x9750,
   1.308 -	0x9850, 0x9950, 0x9450, 0x9550, 0x9650, 0x9750, 0x9850, 0x9950,
   1.309 -	0xA050, 0xA150, 0xA250, 0xA350, 0xA450, 0xA550, 0xA650, 0xA750,
   1.310 -	0xA850, 0xA950, 0xA450, 0xA550, 0xA650, 0xA750, 0xA850, 0xA950,
   1.311 -	0xB050, 0xB150, 0xB250, 0xB350, 0xB450, 0xB550, 0xB650, 0xB750,
   1.312 -	0xB850, 0xB950, 0xB450, 0xB550, 0xB650, 0xB750, 0xB850, 0xB950,
   1.313 -	0xC050, 0xC150, 0xC250, 0xC350, 0xC450, 0xC550, 0xC650, 0xC750,
   1.314 -	0xC850, 0xC950, 0xC450, 0xC550, 0xC650, 0xC750, 0xC850, 0xC950,
   1.315 -	0xD050, 0xD150, 0xD250, 0xD350, 0xD450, 0xD550, 0xD650, 0xD750,
   1.316 -	0xD850, 0xD950, 0xD450, 0xD550, 0xD650, 0xD750, 0xD850, 0xD950,
   1.317 -	0xE050, 0xE150, 0xE250, 0xE350, 0xE450, 0xE550, 0xE650, 0xE750,
   1.318 -	0xE850, 0xE950, 0xE450, 0xE550, 0xE650, 0xE750, 0xE850, 0xE950,
   1.319 -	0xF050, 0xF150, 0xF250, 0xF350, 0xF450, 0xF550, 0xF650, 0xF750,
   1.320 -	0xF850, 0xF950, 0xF450, 0xF550, 0xF650, 0xF750, 0xF850, 0xF950,
   1.321 -	0x00D0, 0x0150, 0x0250, 0x0350, 0x0450, 0x0550, 0x0650, 0x0750,
   1.322 -	0x0850, 0x0950, 0x0450, 0x0550, 0x0650, 0x0750, 0x0850, 0x0950,
   1.323 -	0x1050, 0x1150, 0x1250, 0x1350, 0x1450, 0x1550, 0x1650, 0x1750,
   1.324 -	0x1850, 0x1950, 0x1450, 0x1550, 0x1650, 0x1750, 0x1850, 0x1950,
   1.325 -	0x2050, 0x2150, 0x2250, 0x2350, 0x2450, 0x2550, 0x2650, 0x2750,
   1.326 -	0x2850, 0x2950, 0x2450, 0x2550, 0x2650, 0x2750, 0x2850, 0x2950,
   1.327 -	0x3050, 0x3150, 0x3250, 0x3350, 0x3450, 0x3550, 0x3650, 0x3750,
   1.328 -	0x3850, 0x3950, 0x3450, 0x3550, 0x3650, 0x3750, 0x3850, 0x3950,
   1.329 -	0x4050, 0x4150, 0x4250, 0x4350, 0x4450, 0x4550, 0x4650, 0x4750,
   1.330 -	0x4850, 0x4950, 0x4450, 0x4550, 0x4650, 0x4750, 0x4850, 0x4950,
   1.331 -	0x5050, 0x5150, 0x5250, 0x5350, 0x5450, 0x5550, 0x5650, 0x5750,
   1.332 -	0x5850, 0x5950, 0x5450, 0x5550, 0x5650, 0x5750, 0x5850, 0x5950,
   1.333 -	0x6050, 0x6150, 0x6250, 0x6350, 0x6450, 0x6550, 0x6650, 0x6750,
   1.334 -	0x6850, 0x6950, 0x6450, 0x6550, 0x6650, 0x6750, 0x6850, 0x6950,
   1.335 -	0x7050, 0x7150, 0x7250, 0x7350, 0x7450, 0x7550, 0x7650, 0x7750,
   1.336 -	0x7850, 0x7950, 0x7450, 0x7550, 0x7650, 0x7750, 0x7850, 0x7950,
   1.337 -	0x8050, 0x8150, 0x8250, 0x8350, 0x8450, 0x8550, 0x8650, 0x8750,
   1.338 -	0x8850, 0x8950, 0x8450, 0x8550, 0x8650, 0x8750, 0x8850, 0x8950,
   1.339 -	0x9050, 0x9150, 0x9250, 0x9350, 0x9450, 0x9550, 0x9650, 0x9750,
   1.340 -	0x9850, 0x9950, 0x9450, 0x9550, 0x9650, 0x9750, 0x9850, 0x9950,
   1.341 -	0xFA60, 0xFB60, 0xFC60, 0xFD60, 0xFE60, 0xFF60, 0x00C0, 0x0140,
   1.342 -	0x0240, 0x0340, 0x0440, 0x0540, 0x0640, 0x0740, 0x0840, 0x0940,
   1.343 -	0x0A60, 0x0B60, 0x0C60, 0x0D60, 0x0E60, 0x0F60, 0x1040, 0x1140,
   1.344 -	0x1240, 0x1340, 0x1440, 0x1540, 0x1640, 0x1740, 0x1840, 0x1940,
   1.345 -	0x1A60, 0x1B60, 0x1C60, 0x1D60, 0x1E60, 0x1F60, 0x2040, 0x2140,
   1.346 -	0x2240, 0x2340, 0x2440, 0x2540, 0x2640, 0x2740, 0x2840, 0x2940,
   1.347 -	0x2A60, 0x2B60, 0x2C60, 0x2D60, 0x2E60, 0x2F60, 0x3040, 0x3140,
   1.348 -	0x3240, 0x3340, 0x3440, 0x3540, 0x3640, 0x3740, 0x3840, 0x3940,
   1.349 -	0x3A60, 0x3B60, 0x3C60, 0x3D60, 0x3E60, 0x3F60, 0x4040, 0x4140,
   1.350 -	0x4240, 0x4340, 0x4440, 0x4540, 0x4640, 0x4740, 0x4840, 0x4940,
   1.351 -	0x4A60, 0x4B60, 0x4C60, 0x4D60, 0x4E60, 0x4F60, 0x5040, 0x5140,
   1.352 -	0x5240, 0x5340, 0x5440, 0x5540, 0x5640, 0x5740, 0x5840, 0x5940,
   1.353 -	0x5A60, 0x5B60, 0x5C60, 0x5D60, 0x5E60, 0x5F60, 0x6040, 0x6140,
   1.354 -	0x6240, 0x6340, 0x6440, 0x6540, 0x6640, 0x6740, 0x6840, 0x6940,
   1.355 -	0x6A60, 0x6B60, 0x6C60, 0x6D60, 0x6E60, 0x6F60, 0x7040, 0x7140,
   1.356 -	0x7240, 0x7340, 0x7440, 0x7540, 0x7640, 0x7740, 0x7840, 0x7940,
   1.357 -	0x7A60, 0x7B60, 0x7C60, 0x7D60, 0x7E60, 0x7F60, 0x8040, 0x8140,
   1.358 -	0x8240, 0x8340, 0x8440, 0x8540, 0x8640, 0x8740, 0x8840, 0x8940,
   1.359 -	0x8A60, 0x8B60, 0x8C60, 0x8D60, 0x8E60, 0x8F60, 0x9040, 0x9140,
   1.360 -	0x9240, 0x9340, 0x3450, 0x3550, 0x3650, 0x3750, 0x3850, 0x3950,
   1.361 -	0x3A70, 0x3B70, 0x3C70, 0x3D70, 0x3E70, 0x3F70, 0x4050, 0x4150,
   1.362 -	0x4250, 0x4350, 0x4450, 0x4550, 0x4650, 0x4750, 0x4850, 0x4950,
   1.363 -	0x4A70, 0x4B70, 0x4C70, 0x4D70, 0x4E70, 0x4F70, 0x5050, 0x5150,
   1.364 -	0x5250, 0x5350, 0x5450, 0x5550, 0x5650, 0x5750, 0x5850, 0x5950,
   1.365 -	0x5A70, 0x5B70, 0x5C70, 0x5D70, 0x5E70, 0x5F70, 0x6050, 0x6150,
   1.366 -	0x6250, 0x6350, 0x6450, 0x6550, 0x6650, 0x6750, 0x6850, 0x6950,
   1.367 -	0x6A70, 0x6B70, 0x6C70, 0x6D70, 0x6E70, 0x6F70, 0x7050, 0x7150,
   1.368 -	0x7250, 0x7350, 0x7450, 0x7550, 0x7650, 0x7750, 0x7850, 0x7950,
   1.369 -	0x7A70, 0x7B70, 0x7C70, 0x7D70, 0x7E70, 0x7F70, 0x8050, 0x8150,
   1.370 -	0x8250, 0x8350, 0x8450, 0x8550, 0x8650, 0x8750, 0x8850, 0x8950,
   1.371 -	0x8A70, 0x8B70, 0x8C70, 0x8D70, 0x8E70, 0x8F70, 0x9050, 0x9150,
   1.372 -	0x9250, 0x9350, 0x9450, 0x9550, 0x9650, 0x9750, 0x9850, 0x9950,
   1.373 -	0x9A70, 0x9B70, 0x9C70, 0x9D70, 0x9E70, 0x9F70, 0xA050, 0xA150,
   1.374 -	0xA250, 0xA350, 0xA450, 0xA550, 0xA650, 0xA750, 0xA850, 0xA950,
   1.375 -	0xAA70, 0xAB70, 0xAC70, 0xAD70, 0xAE70, 0xAF70, 0xB050, 0xB150,
   1.376 -	0xB250, 0xB350, 0xB450, 0xB550, 0xB650, 0xB750, 0xB850, 0xB950,
   1.377 -	0xBA70, 0xBB70, 0xBC70, 0xBD70, 0xBE70, 0xBF70, 0xC050, 0xC150,
   1.378 -	0xC250, 0xC350, 0xC450, 0xC550, 0xC650, 0xC750, 0xC850, 0xC950,
   1.379 -	0xCA70, 0xCB70, 0xCC70, 0xCD70, 0xCE70, 0xCF70, 0xD050, 0xD150,
   1.380 -	0xD250, 0xD350, 0xD450, 0xD550, 0xD650, 0xD750, 0xD850, 0xD950,
   1.381 -	0xDA70, 0xDB70, 0xDC70, 0xDD70, 0xDE70, 0xDF70, 0xE050, 0xE150,
   1.382 -	0xE250, 0xE350, 0xE450, 0xE550, 0xE650, 0xE750, 0xE850, 0xE950,
   1.383 -	0xEA70, 0xEB70, 0xEC70, 0xED70, 0xEE70, 0xEF70, 0xF050, 0xF150,
   1.384 -	0xF250, 0xF350, 0xF450, 0xF550, 0xF650, 0xF750, 0xF850, 0xF950,
   1.385 -	0xFA70, 0xFB70, 0xFC70, 0xFD70, 0xFE70, 0xFF70, 0x00D0, 0x0150,
   1.386 -	0x0250, 0x0350, 0x0450, 0x0550, 0x0650, 0x0750, 0x0850, 0x0950,
   1.387 -	0x0A70, 0x0B70, 0x0C70, 0x0D70, 0x0E70, 0x0F70, 0x1050, 0x1150,
   1.388 -	0x1250, 0x1350, 0x1450, 0x1550, 0x1650, 0x1750, 0x1850, 0x1950,
   1.389 -	0x1A70, 0x1B70, 0x1C70, 0x1D70, 0x1E70, 0x1F70, 0x2050, 0x2150,
   1.390 -	0x2250, 0x2350, 0x2450, 0x2550, 0x2650, 0x2750, 0x2850, 0x2950,
   1.391 -	0x2A70, 0x2B70, 0x2C70, 0x2D70, 0x2E70, 0x2F70, 0x3050, 0x3150,
   1.392 -	0x3250, 0x3350, 0x3450, 0x3550, 0x3650, 0x3750, 0x3850, 0x3950,
   1.393 -	0x3A70, 0x3B70, 0x3C70, 0x3D70, 0x3E70, 0x3F70, 0x4050, 0x4150,
   1.394 -	0x4250, 0x4350, 0x4450, 0x4550, 0x4650, 0x4750, 0x4850, 0x4950,
   1.395 -	0x4A70, 0x4B70, 0x4C70, 0x4D70, 0x4E70, 0x4F70, 0x5050, 0x5150,
   1.396 -	0x5250, 0x5350, 0x5450, 0x5550, 0x5650, 0x5750, 0x5850, 0x5950,
   1.397 -	0x5A70, 0x5B70, 0x5C70, 0x5D70, 0x5E70, 0x5F70, 0x6050, 0x6150,
   1.398 -	0x6250, 0x6350, 0x6450, 0x6550, 0x6650, 0x6750, 0x6850, 0x6950,
   1.399 -	0x6A70, 0x6B70, 0x6C70, 0x6D70, 0x6E70, 0x6F70, 0x7050, 0x7150,
   1.400 -	0x7250, 0x7350, 0x7450, 0x7550, 0x7650, 0x7750, 0x7850, 0x7950,
   1.401 -	0x7A70, 0x7B70, 0x7C70, 0x7D70, 0x7E70, 0x7F70, 0x8050, 0x8150,
   1.402 -	0x8250, 0x8350, 0x8450, 0x8550, 0x8650, 0x8750, 0x8850, 0x8950,
   1.403 -	0x8A70, 0x8B70, 0x8C70, 0x8D70, 0x8E70, 0x8F70, 0x9050, 0x9150,
   1.404 -	0x9250, 0x9350, 0x9450, 0x9550, 0x9650, 0x9750, 0x9850, 0x9950,
   1.405 -};
   1.406 +  {
   1.407 +    0x0080, 0x0100, 0x0200, 0x0300, 0x0400, 0x0500, 0x0600, 0x0700,
   1.408 +    0x0800, 0x0900, 0x1020, 0x1120, 0x1220, 0x1320, 0x1420, 0x1520,
   1.409 +    0x1000, 0x1100, 0x1200, 0x1300, 0x1400, 0x1500, 0x1600, 0x1700,
   1.410 +    0x1800, 0x1900, 0x2020, 0x2120, 0x2220, 0x2320, 0x2420, 0x2520,
   1.411 +    0x2000, 0x2100, 0x2200, 0x2300, 0x2400, 0x2500, 0x2600, 0x2700,
   1.412 +    0x2800, 0x2900, 0x3020, 0x3120, 0x3220, 0x3320, 0x3420, 0x3520,
   1.413 +    0x3000, 0x3100, 0x3200, 0x3300, 0x3400, 0x3500, 0x3600, 0x3700,
   1.414 +    0x3800, 0x3900, 0x4020, 0x4120, 0x4220, 0x4320, 0x4420, 0x4520,
   1.415 +    0x4000, 0x4100, 0x4200, 0x4300, 0x4400, 0x4500, 0x4600, 0x4700,
   1.416 +    0x4800, 0x4900, 0x5020, 0x5120, 0x5220, 0x5320, 0x5420, 0x5520,
   1.417 +    0x5000, 0x5100, 0x5200, 0x5300, 0x5400, 0x5500, 0x5600, 0x5700,
   1.418 +    0x5800, 0x5900, 0x6020, 0x6120, 0x6220, 0x6320, 0x6420, 0x6520,
   1.419 +    0x6000, 0x6100, 0x6200, 0x6300, 0x6400, 0x6500, 0x6600, 0x6700,
   1.420 +    0x6800, 0x6900, 0x7020, 0x7120, 0x7220, 0x7320, 0x7420, 0x7520,
   1.421 +    0x7000, 0x7100, 0x7200, 0x7300, 0x7400, 0x7500, 0x7600, 0x7700,
   1.422 +    0x7800, 0x7900, 0x8020, 0x8120, 0x8220, 0x8320, 0x8420, 0x8520,
   1.423 +    0x8000, 0x8100, 0x8200, 0x8300, 0x8400, 0x8500, 0x8600, 0x8700,
   1.424 +    0x8800, 0x8900, 0x9020, 0x9120, 0x9220, 0x9320, 0x9420, 0x9520,
   1.425 +    0x9000, 0x9100, 0x9200, 0x9300, 0x9400, 0x9500, 0x9600, 0x9700,
   1.426 +    0x9800, 0x9900, 0x00B0, 0x0130, 0x0230, 0x0330, 0x0430, 0x0530,
   1.427 +    0x0090, 0x0110, 0x0210, 0x0310, 0x0410, 0x0510, 0x0610, 0x0710,
   1.428 +    0x0810, 0x0910, 0x1030, 0x1130, 0x1230, 0x1330, 0x1430, 0x1530,
   1.429 +    0x1010, 0x1110, 0x1210, 0x1310, 0x1410, 0x1510, 0x1610, 0x1710,
   1.430 +    0x1810, 0x1910, 0x2030, 0x2130, 0x2230, 0x2330, 0x2430, 0x2530,
   1.431 +    0x2010, 0x2110, 0x2210, 0x2310, 0x2410, 0x2510, 0x2610, 0x2710,
   1.432 +    0x2810, 0x2910, 0x3030, 0x3130, 0x3230, 0x3330, 0x3430, 0x3530,
   1.433 +    0x3010, 0x3110, 0x3210, 0x3310, 0x3410, 0x3510, 0x3610, 0x3710,
   1.434 +    0x3810, 0x3910, 0x4030, 0x4130, 0x4230, 0x4330, 0x4430, 0x4530,
   1.435 +    0x4010, 0x4110, 0x4210, 0x4310, 0x4410, 0x4510, 0x4610, 0x4710,
   1.436 +    0x4810, 0x4910, 0x5030, 0x5130, 0x5230, 0x5330, 0x5430, 0x5530,
   1.437 +    0x5010, 0x5110, 0x5210, 0x5310, 0x5410, 0x5510, 0x5610, 0x5710,
   1.438 +    0x5810, 0x5910, 0x6030, 0x6130, 0x6230, 0x6330, 0x6430, 0x6530,
   1.439 +    0x6010, 0x6110, 0x6210, 0x6310, 0x6410, 0x6510, 0x6610, 0x6710,
   1.440 +    0x6810, 0x6910, 0x7030, 0x7130, 0x7230, 0x7330, 0x7430, 0x7530,
   1.441 +    0x7010, 0x7110, 0x7210, 0x7310, 0x7410, 0x7510, 0x7610, 0x7710,
   1.442 +    0x7810, 0x7910, 0x8030, 0x8130, 0x8230, 0x8330, 0x8430, 0x8530,
   1.443 +    0x8010, 0x8110, 0x8210, 0x8310, 0x8410, 0x8510, 0x8610, 0x8710,
   1.444 +    0x8810, 0x8910, 0x9030, 0x9130, 0x9230, 0x9330, 0x9430, 0x9530,
   1.445 +    0x9010, 0x9110, 0x9210, 0x9310, 0x9410, 0x9510, 0x9610, 0x9710,
   1.446 +    0x9810, 0x9910, 0xA030, 0xA130, 0xA230, 0xA330, 0xA430, 0xA530,
   1.447 +    0xA010, 0xA110, 0xA210, 0xA310, 0xA410, 0xA510, 0xA610, 0xA710,
   1.448 +    0xA810, 0xA910, 0xB030, 0xB130, 0xB230, 0xB330, 0xB430, 0xB530,
   1.449 +    0xB010, 0xB110, 0xB210, 0xB310, 0xB410, 0xB510, 0xB610, 0xB710,
   1.450 +    0xB810, 0xB910, 0xC030, 0xC130, 0xC230, 0xC330, 0xC430, 0xC530,
   1.451 +    0xC010, 0xC110, 0xC210, 0xC310, 0xC410, 0xC510, 0xC610, 0xC710,
   1.452 +    0xC810, 0xC910, 0xD030, 0xD130, 0xD230, 0xD330, 0xD430, 0xD530,
   1.453 +    0xD010, 0xD110, 0xD210, 0xD310, 0xD410, 0xD510, 0xD610, 0xD710,
   1.454 +    0xD810, 0xD910, 0xE030, 0xE130, 0xE230, 0xE330, 0xE430, 0xE530,
   1.455 +    0xE010, 0xE110, 0xE210, 0xE310, 0xE410, 0xE510, 0xE610, 0xE710,
   1.456 +    0xE810, 0xE910, 0xF030, 0xF130, 0xF230, 0xF330, 0xF430, 0xF530,
   1.457 +    0xF010, 0xF110, 0xF210, 0xF310, 0xF410, 0xF510, 0xF610, 0xF710,
   1.458 +    0xF810, 0xF910, 0x00B0, 0x0130, 0x0230, 0x0330, 0x0430, 0x0530,
   1.459 +    0x0090, 0x0110, 0x0210, 0x0310, 0x0410, 0x0510, 0x0610, 0x0710,
   1.460 +    0x0810, 0x0910, 0x1030, 0x1130, 0x1230, 0x1330, 0x1430, 0x1530,
   1.461 +    0x1010, 0x1110, 0x1210, 0x1310, 0x1410, 0x1510, 0x1610, 0x1710,
   1.462 +    0x1810, 0x1910, 0x2030, 0x2130, 0x2230, 0x2330, 0x2430, 0x2530,
   1.463 +    0x2010, 0x2110, 0x2210, 0x2310, 0x2410, 0x2510, 0x2610, 0x2710,
   1.464 +    0x2810, 0x2910, 0x3030, 0x3130, 0x3230, 0x3330, 0x3430, 0x3530,
   1.465 +    0x3010, 0x3110, 0x3210, 0x3310, 0x3410, 0x3510, 0x3610, 0x3710,
   1.466 +    0x3810, 0x3910, 0x4030, 0x4130, 0x4230, 0x4330, 0x4430, 0x4530,
   1.467 +    0x4010, 0x4110, 0x4210, 0x4310, 0x4410, 0x4510, 0x4610, 0x4710,
   1.468 +    0x4810, 0x4910, 0x5030, 0x5130, 0x5230, 0x5330, 0x5430, 0x5530,
   1.469 +    0x5010, 0x5110, 0x5210, 0x5310, 0x5410, 0x5510, 0x5610, 0x5710,
   1.470 +    0x5810, 0x5910, 0x6030, 0x6130, 0x6230, 0x6330, 0x6430, 0x6530,
   1.471 +    0x0600, 0x0700, 0x0800, 0x0900, 0x0A00, 0x0B00, 0x0C00, 0x0D00,
   1.472 +    0x0E00, 0x0F00, 0x1020, 0x1120, 0x1220, 0x1320, 0x1420, 0x1520,
   1.473 +    0x1600, 0x1700, 0x1800, 0x1900, 0x1A00, 0x1B00, 0x1C00, 0x1D00,
   1.474 +    0x1E00, 0x1F00, 0x2020, 0x2120, 0x2220, 0x2320, 0x2420, 0x2520,
   1.475 +    0x2600, 0x2700, 0x2800, 0x2900, 0x2A00, 0x2B00, 0x2C00, 0x2D00,
   1.476 +    0x2E00, 0x2F00, 0x3020, 0x3120, 0x3220, 0x3320, 0x3420, 0x3520,
   1.477 +    0x3600, 0x3700, 0x3800, 0x3900, 0x3A00, 0x3B00, 0x3C00, 0x3D00,
   1.478 +    0x3E00, 0x3F00, 0x4020, 0x4120, 0x4220, 0x4320, 0x4420, 0x4520,
   1.479 +    0x4600, 0x4700, 0x4800, 0x4900, 0x4A00, 0x4B00, 0x4C00, 0x4D00,
   1.480 +    0x4E00, 0x4F00, 0x5020, 0x5120, 0x5220, 0x5320, 0x5420, 0x5520,
   1.481 +    0x5600, 0x5700, 0x5800, 0x5900, 0x5A00, 0x5B00, 0x5C00, 0x5D00,
   1.482 +    0x5E00, 0x5F00, 0x6020, 0x6120, 0x6220, 0x6320, 0x6420, 0x6520,
   1.483 +    0x6600, 0x6700, 0x6800, 0x6900, 0x6A00, 0x6B00, 0x6C00, 0x6D00,
   1.484 +    0x6E00, 0x6F00, 0x7020, 0x7120, 0x7220, 0x7320, 0x7420, 0x7520,
   1.485 +    0x7600, 0x7700, 0x7800, 0x7900, 0x7A00, 0x7B00, 0x7C00, 0x7D00,
   1.486 +    0x7E00, 0x7F00, 0x8020, 0x8120, 0x8220, 0x8320, 0x8420, 0x8520,
   1.487 +    0x8600, 0x8700, 0x8800, 0x8900, 0x8A00, 0x8B00, 0x8C00, 0x8D00,
   1.488 +    0x8E00, 0x8F00, 0x9020, 0x9120, 0x9220, 0x9320, 0x9420, 0x9520,
   1.489 +    0x9600, 0x9700, 0x9800, 0x9900, 0x9A00, 0x9B00, 0x9C00, 0x9D00,
   1.490 +    0x9E00, 0x9F00, 0x00B0, 0x0130, 0x0230, 0x0330, 0x0430, 0x0530,
   1.491 +    0x0610, 0x0710, 0x0810, 0x0910, 0x0A10, 0x0B10, 0x0C10, 0x0D10,
   1.492 +    0x0E10, 0x0F10, 0x1030, 0x1130, 0x1230, 0x1330, 0x1430, 0x1530,
   1.493 +    0x1610, 0x1710, 0x1810, 0x1910, 0x1A10, 0x1B10, 0x1C10, 0x1D10,
   1.494 +    0x1E10, 0x1F10, 0x2030, 0x2130, 0x2230, 0x2330, 0x2430, 0x2530,
   1.495 +    0x2610, 0x2710, 0x2810, 0x2910, 0x2A10, 0x2B10, 0x2C10, 0x2D10,
   1.496 +    0x2E10, 0x2F10, 0x3030, 0x3130, 0x3230, 0x3330, 0x3430, 0x3530,
   1.497 +    0x3610, 0x3710, 0x3810, 0x3910, 0x3A10, 0x3B10, 0x3C10, 0x3D10,
   1.498 +    0x3E10, 0x3F10, 0x4030, 0x4130, 0x4230, 0x4330, 0x4430, 0x4530,
   1.499 +    0x4610, 0x4710, 0x4810, 0x4910, 0x4A10, 0x4B10, 0x4C10, 0x4D10,
   1.500 +    0x4E10, 0x4F10, 0x5030, 0x5130, 0x5230, 0x5330, 0x5430, 0x5530,
   1.501 +    0x5610, 0x5710, 0x5810, 0x5910, 0x5A10, 0x5B10, 0x5C10, 0x5D10,
   1.502 +    0x5E10, 0x5F10, 0x6030, 0x6130, 0x6230, 0x6330, 0x6430, 0x6530,
   1.503 +    0x6610, 0x6710, 0x6810, 0x6910, 0x6A10, 0x6B10, 0x6C10, 0x6D10,
   1.504 +    0x6E10, 0x6F10, 0x7030, 0x7130, 0x7230, 0x7330, 0x7430, 0x7530,
   1.505 +    0x7610, 0x7710, 0x7810, 0x7910, 0x7A10, 0x7B10, 0x7C10, 0x7D10,
   1.506 +    0x7E10, 0x7F10, 0x8030, 0x8130, 0x8230, 0x8330, 0x8430, 0x8530,
   1.507 +    0x8610, 0x8710, 0x8810, 0x8910, 0x8A10, 0x8B10, 0x8C10, 0x8D10,
   1.508 +    0x8E10, 0x8F10, 0x9030, 0x9130, 0x9230, 0x9330, 0x9430, 0x9530,
   1.509 +    0x9610, 0x9710, 0x9810, 0x9910, 0x9A10, 0x9B10, 0x9C10, 0x9D10,
   1.510 +    0x9E10, 0x9F10, 0xA030, 0xA130, 0xA230, 0xA330, 0xA430, 0xA530,
   1.511 +    0xA610, 0xA710, 0xA810, 0xA910, 0xAA10, 0xAB10, 0xAC10, 0xAD10,
   1.512 +    0xAE10, 0xAF10, 0xB030, 0xB130, 0xB230, 0xB330, 0xB430, 0xB530,
   1.513 +    0xB610, 0xB710, 0xB810, 0xB910, 0xBA10, 0xBB10, 0xBC10, 0xBD10,
   1.514 +    0xBE10, 0xBF10, 0xC030, 0xC130, 0xC230, 0xC330, 0xC430, 0xC530,
   1.515 +    0xC610, 0xC710, 0xC810, 0xC910, 0xCA10, 0xCB10, 0xCC10, 0xCD10,
   1.516 +    0xCE10, 0xCF10, 0xD030, 0xD130, 0xD230, 0xD330, 0xD430, 0xD530,
   1.517 +    0xD610, 0xD710, 0xD810, 0xD910, 0xDA10, 0xDB10, 0xDC10, 0xDD10,
   1.518 +    0xDE10, 0xDF10, 0xE030, 0xE130, 0xE230, 0xE330, 0xE430, 0xE530,
   1.519 +    0xE610, 0xE710, 0xE810, 0xE910, 0xEA10, 0xEB10, 0xEC10, 0xED10,
   1.520 +    0xEE10, 0xEF10, 0xF030, 0xF130, 0xF230, 0xF330, 0xF430, 0xF530,
   1.521 +    0xF610, 0xF710, 0xF810, 0xF910, 0xFA10, 0xFB10, 0xFC10, 0xFD10,
   1.522 +    0xFE10, 0xFF10, 0x00B0, 0x0130, 0x0230, 0x0330, 0x0430, 0x0530,
   1.523 +    0x0610, 0x0710, 0x0810, 0x0910, 0x0A10, 0x0B10, 0x0C10, 0x0D10,
   1.524 +    0x0E10, 0x0F10, 0x1030, 0x1130, 0x1230, 0x1330, 0x1430, 0x1530,
   1.525 +    0x1610, 0x1710, 0x1810, 0x1910, 0x1A10, 0x1B10, 0x1C10, 0x1D10,
   1.526 +    0x1E10, 0x1F10, 0x2030, 0x2130, 0x2230, 0x2330, 0x2430, 0x2530,
   1.527 +    0x2610, 0x2710, 0x2810, 0x2910, 0x2A10, 0x2B10, 0x2C10, 0x2D10,
   1.528 +    0x2E10, 0x2F10, 0x3030, 0x3130, 0x3230, 0x3330, 0x3430, 0x3530,
   1.529 +    0x3610, 0x3710, 0x3810, 0x3910, 0x3A10, 0x3B10, 0x3C10, 0x3D10,
   1.530 +    0x3E10, 0x3F10, 0x4030, 0x4130, 0x4230, 0x4330, 0x4430, 0x4530,
   1.531 +    0x4610, 0x4710, 0x4810, 0x4910, 0x4A10, 0x4B10, 0x4C10, 0x4D10,
   1.532 +    0x4E10, 0x4F10, 0x5030, 0x5130, 0x5230, 0x5330, 0x5430, 0x5530,
   1.533 +    0x5610, 0x5710, 0x5810, 0x5910, 0x5A10, 0x5B10, 0x5C10, 0x5D10,
   1.534 +    0x5E10, 0x5F10, 0x6030, 0x6130, 0x6230, 0x6330, 0x6430, 0x6530,
   1.535 +    0x00C0, 0x0140, 0x0240, 0x0340, 0x0440, 0x0540, 0x0640, 0x0740,
   1.536 +    0x0840, 0x0940, 0x0440, 0x0540, 0x0640, 0x0740, 0x0840, 0x0940,
   1.537 +    0x1040, 0x1140, 0x1240, 0x1340, 0x1440, 0x1540, 0x1640, 0x1740,
   1.538 +    0x1840, 0x1940, 0x1440, 0x1540, 0x1640, 0x1740, 0x1840, 0x1940,
   1.539 +    0x2040, 0x2140, 0x2240, 0x2340, 0x2440, 0x2540, 0x2640, 0x2740,
   1.540 +    0x2840, 0x2940, 0x2440, 0x2540, 0x2640, 0x2740, 0x2840, 0x2940,
   1.541 +    0x3040, 0x3140, 0x3240, 0x3340, 0x3440, 0x3540, 0x3640, 0x3740,
   1.542 +    0x3840, 0x3940, 0x3440, 0x3540, 0x3640, 0x3740, 0x3840, 0x3940,
   1.543 +    0x4040, 0x4140, 0x4240, 0x4340, 0x4440, 0x4540, 0x4640, 0x4740,
   1.544 +    0x4840, 0x4940, 0x4440, 0x4540, 0x4640, 0x4740, 0x4840, 0x4940,
   1.545 +    0x5040, 0x5140, 0x5240, 0x5340, 0x5440, 0x5540, 0x5640, 0x5740,
   1.546 +    0x5840, 0x5940, 0x5440, 0x5540, 0x5640, 0x5740, 0x5840, 0x5940,
   1.547 +    0x6040, 0x6140, 0x6240, 0x6340, 0x6440, 0x6540, 0x6640, 0x6740,
   1.548 +    0x6840, 0x6940, 0x6440, 0x6540, 0x6640, 0x6740, 0x6840, 0x6940,
   1.549 +    0x7040, 0x7140, 0x7240, 0x7340, 0x7440, 0x7540, 0x7640, 0x7740,
   1.550 +    0x7840, 0x7940, 0x7440, 0x7540, 0x7640, 0x7740, 0x7840, 0x7940,
   1.551 +    0x8040, 0x8140, 0x8240, 0x8340, 0x8440, 0x8540, 0x8640, 0x8740,
   1.552 +    0x8840, 0x8940, 0x8440, 0x8540, 0x8640, 0x8740, 0x8840, 0x8940,
   1.553 +    0x9040, 0x9140, 0x9240, 0x9340, 0x9440, 0x9540, 0x9640, 0x9740,
   1.554 +    0x9840, 0x9940, 0x3450, 0x3550, 0x3650, 0x3750, 0x3850, 0x3950,
   1.555 +    0x4050, 0x4150, 0x4250, 0x4350, 0x4450, 0x4550, 0x4650, 0x4750,
   1.556 +    0x4850, 0x4950, 0x4450, 0x4550, 0x4650, 0x4750, 0x4850, 0x4950,
   1.557 +    0x5050, 0x5150, 0x5250, 0x5350, 0x5450, 0x5550, 0x5650, 0x5750,
   1.558 +    0x5850, 0x5950, 0x5450, 0x5550, 0x5650, 0x5750, 0x5850, 0x5950,
   1.559 +    0x6050, 0x6150, 0x6250, 0x6350, 0x6450, 0x6550, 0x6650, 0x6750,
   1.560 +    0x6850, 0x6950, 0x6450, 0x6550, 0x6650, 0x6750, 0x6850, 0x6950,
   1.561 +    0x7050, 0x7150, 0x7250, 0x7350, 0x7450, 0x7550, 0x7650, 0x7750,
   1.562 +    0x7850, 0x7950, 0x7450, 0x7550, 0x7650, 0x7750, 0x7850, 0x7950,
   1.563 +    0x8050, 0x8150, 0x8250, 0x8350, 0x8450, 0x8550, 0x8650, 0x8750,
   1.564 +    0x8850, 0x8950, 0x8450, 0x8550, 0x8650, 0x8750, 0x8850, 0x8950,
   1.565 +    0x9050, 0x9150, 0x9250, 0x9350, 0x9450, 0x9550, 0x9650, 0x9750,
   1.566 +    0x9850, 0x9950, 0x9450, 0x9550, 0x9650, 0x9750, 0x9850, 0x9950,
   1.567 +    0xA050, 0xA150, 0xA250, 0xA350, 0xA450, 0xA550, 0xA650, 0xA750,
   1.568 +    0xA850, 0xA950, 0xA450, 0xA550, 0xA650, 0xA750, 0xA850, 0xA950,
   1.569 +    0xB050, 0xB150, 0xB250, 0xB350, 0xB450, 0xB550, 0xB650, 0xB750,
   1.570 +    0xB850, 0xB950, 0xB450, 0xB550, 0xB650, 0xB750, 0xB850, 0xB950,
   1.571 +    0xC050, 0xC150, 0xC250, 0xC350, 0xC450, 0xC550, 0xC650, 0xC750,
   1.572 +    0xC850, 0xC950, 0xC450, 0xC550, 0xC650, 0xC750, 0xC850, 0xC950,
   1.573 +    0xD050, 0xD150, 0xD250, 0xD350, 0xD450, 0xD550, 0xD650, 0xD750,
   1.574 +    0xD850, 0xD950, 0xD450, 0xD550, 0xD650, 0xD750, 0xD850, 0xD950,
   1.575 +    0xE050, 0xE150, 0xE250, 0xE350, 0xE450, 0xE550, 0xE650, 0xE750,
   1.576 +    0xE850, 0xE950, 0xE450, 0xE550, 0xE650, 0xE750, 0xE850, 0xE950,
   1.577 +    0xF050, 0xF150, 0xF250, 0xF350, 0xF450, 0xF550, 0xF650, 0xF750,
   1.578 +    0xF850, 0xF950, 0xF450, 0xF550, 0xF650, 0xF750, 0xF850, 0xF950,
   1.579 +    0x00D0, 0x0150, 0x0250, 0x0350, 0x0450, 0x0550, 0x0650, 0x0750,
   1.580 +    0x0850, 0x0950, 0x0450, 0x0550, 0x0650, 0x0750, 0x0850, 0x0950,
   1.581 +    0x1050, 0x1150, 0x1250, 0x1350, 0x1450, 0x1550, 0x1650, 0x1750,
   1.582 +    0x1850, 0x1950, 0x1450, 0x1550, 0x1650, 0x1750, 0x1850, 0x1950,
   1.583 +    0x2050, 0x2150, 0x2250, 0x2350, 0x2450, 0x2550, 0x2650, 0x2750,
   1.584 +    0x2850, 0x2950, 0x2450, 0x2550, 0x2650, 0x2750, 0x2850, 0x2950,
   1.585 +    0x3050, 0x3150, 0x3250, 0x3350, 0x3450, 0x3550, 0x3650, 0x3750,
   1.586 +    0x3850, 0x3950, 0x3450, 0x3550, 0x3650, 0x3750, 0x3850, 0x3950,
   1.587 +    0x4050, 0x4150, 0x4250, 0x4350, 0x4450, 0x4550, 0x4650, 0x4750,
   1.588 +    0x4850, 0x4950, 0x4450, 0x4550, 0x4650, 0x4750, 0x4850, 0x4950,
   1.589 +    0x5050, 0x5150, 0x5250, 0x5350, 0x5450, 0x5550, 0x5650, 0x5750,
   1.590 +    0x5850, 0x5950, 0x5450, 0x5550, 0x5650, 0x5750, 0x5850, 0x5950,
   1.591 +    0x6050, 0x6150, 0x6250, 0x6350, 0x6450, 0x6550, 0x6650, 0x6750,
   1.592 +    0x6850, 0x6950, 0x6450, 0x6550, 0x6650, 0x6750, 0x6850, 0x6950,
   1.593 +    0x7050, 0x7150, 0x7250, 0x7350, 0x7450, 0x7550, 0x7650, 0x7750,
   1.594 +    0x7850, 0x7950, 0x7450, 0x7550, 0x7650, 0x7750, 0x7850, 0x7950,
   1.595 +    0x8050, 0x8150, 0x8250, 0x8350, 0x8450, 0x8550, 0x8650, 0x8750,
   1.596 +    0x8850, 0x8950, 0x8450, 0x8550, 0x8650, 0x8750, 0x8850, 0x8950,
   1.597 +    0x9050, 0x9150, 0x9250, 0x9350, 0x9450, 0x9550, 0x9650, 0x9750,
   1.598 +    0x9850, 0x9950, 0x9450, 0x9550, 0x9650, 0x9750, 0x9850, 0x9950,
   1.599 +    0xFA60, 0xFB60, 0xFC60, 0xFD60, 0xFE60, 0xFF60, 0x00C0, 0x0140,
   1.600 +    0x0240, 0x0340, 0x0440, 0x0540, 0x0640, 0x0740, 0x0840, 0x0940,
   1.601 +    0x0A60, 0x0B60, 0x0C60, 0x0D60, 0x0E60, 0x0F60, 0x1040, 0x1140,
   1.602 +    0x1240, 0x1340, 0x1440, 0x1540, 0x1640, 0x1740, 0x1840, 0x1940,
   1.603 +    0x1A60, 0x1B60, 0x1C60, 0x1D60, 0x1E60, 0x1F60, 0x2040, 0x2140,
   1.604 +    0x2240, 0x2340, 0x2440, 0x2540, 0x2640, 0x2740, 0x2840, 0x2940,
   1.605 +    0x2A60, 0x2B60, 0x2C60, 0x2D60, 0x2E60, 0x2F60, 0x3040, 0x3140,
   1.606 +    0x3240, 0x3340, 0x3440, 0x3540, 0x3640, 0x3740, 0x3840, 0x3940,
   1.607 +    0x3A60, 0x3B60, 0x3C60, 0x3D60, 0x3E60, 0x3F60, 0x4040, 0x4140,
   1.608 +    0x4240, 0x4340, 0x4440, 0x4540, 0x4640, 0x4740, 0x4840, 0x4940,
   1.609 +    0x4A60, 0x4B60, 0x4C60, 0x4D60, 0x4E60, 0x4F60, 0x5040, 0x5140,
   1.610 +    0x5240, 0x5340, 0x5440, 0x5540, 0x5640, 0x5740, 0x5840, 0x5940,
   1.611 +    0x5A60, 0x5B60, 0x5C60, 0x5D60, 0x5E60, 0x5F60, 0x6040, 0x6140,
   1.612 +    0x6240, 0x6340, 0x6440, 0x6540, 0x6640, 0x6740, 0x6840, 0x6940,
   1.613 +    0x6A60, 0x6B60, 0x6C60, 0x6D60, 0x6E60, 0x6F60, 0x7040, 0x7140,
   1.614 +    0x7240, 0x7340, 0x7440, 0x7540, 0x7640, 0x7740, 0x7840, 0x7940,
   1.615 +    0x7A60, 0x7B60, 0x7C60, 0x7D60, 0x7E60, 0x7F60, 0x8040, 0x8140,
   1.616 +    0x8240, 0x8340, 0x8440, 0x8540, 0x8640, 0x8740, 0x8840, 0x8940,
   1.617 +    0x8A60, 0x8B60, 0x8C60, 0x8D60, 0x8E60, 0x8F60, 0x9040, 0x9140,
   1.618 +    0x9240, 0x9340, 0x3450, 0x3550, 0x3650, 0x3750, 0x3850, 0x3950,
   1.619 +    0x3A70, 0x3B70, 0x3C70, 0x3D70, 0x3E70, 0x3F70, 0x4050, 0x4150,
   1.620 +    0x4250, 0x4350, 0x4450, 0x4550, 0x4650, 0x4750, 0x4850, 0x4950,
   1.621 +    0x4A70, 0x4B70, 0x4C70, 0x4D70, 0x4E70, 0x4F70, 0x5050, 0x5150,
   1.622 +    0x5250, 0x5350, 0x5450, 0x5550, 0x5650, 0x5750, 0x5850, 0x5950,
   1.623 +    0x5A70, 0x5B70, 0x5C70, 0x5D70, 0x5E70, 0x5F70, 0x6050, 0x6150,
   1.624 +    0x6250, 0x6350, 0x6450, 0x6550, 0x6650, 0x6750, 0x6850, 0x6950,
   1.625 +    0x6A70, 0x6B70, 0x6C70, 0x6D70, 0x6E70, 0x6F70, 0x7050, 0x7150,
   1.626 +    0x7250, 0x7350, 0x7450, 0x7550, 0x7650, 0x7750, 0x7850, 0x7950,
   1.627 +    0x7A70, 0x7B70, 0x7C70, 0x7D70, 0x7E70, 0x7F70, 0x8050, 0x8150,
   1.628 +    0x8250, 0x8350, 0x8450, 0x8550, 0x8650, 0x8750, 0x8850, 0x8950,
   1.629 +    0x8A70, 0x8B70, 0x8C70, 0x8D70, 0x8E70, 0x8F70, 0x9050, 0x9150,
   1.630 +    0x9250, 0x9350, 0x9450, 0x9550, 0x9650, 0x9750, 0x9850, 0x9950,
   1.631 +    0x9A70, 0x9B70, 0x9C70, 0x9D70, 0x9E70, 0x9F70, 0xA050, 0xA150,
   1.632 +    0xA250, 0xA350, 0xA450, 0xA550, 0xA650, 0xA750, 0xA850, 0xA950,
   1.633 +    0xAA70, 0xAB70, 0xAC70, 0xAD70, 0xAE70, 0xAF70, 0xB050, 0xB150,
   1.634 +    0xB250, 0xB350, 0xB450, 0xB550, 0xB650, 0xB750, 0xB850, 0xB950,
   1.635 +    0xBA70, 0xBB70, 0xBC70, 0xBD70, 0xBE70, 0xBF70, 0xC050, 0xC150,
   1.636 +    0xC250, 0xC350, 0xC450, 0xC550, 0xC650, 0xC750, 0xC850, 0xC950,
   1.637 +    0xCA70, 0xCB70, 0xCC70, 0xCD70, 0xCE70, 0xCF70, 0xD050, 0xD150,
   1.638 +    0xD250, 0xD350, 0xD450, 0xD550, 0xD650, 0xD750, 0xD850, 0xD950,
   1.639 +    0xDA70, 0xDB70, 0xDC70, 0xDD70, 0xDE70, 0xDF70, 0xE050, 0xE150,
   1.640 +    0xE250, 0xE350, 0xE450, 0xE550, 0xE650, 0xE750, 0xE850, 0xE950,
   1.641 +    0xEA70, 0xEB70, 0xEC70, 0xED70, 0xEE70, 0xEF70, 0xF050, 0xF150,
   1.642 +    0xF250, 0xF350, 0xF450, 0xF550, 0xF650, 0xF750, 0xF850, 0xF950,
   1.643 +    0xFA70, 0xFB70, 0xFC70, 0xFD70, 0xFE70, 0xFF70, 0x00D0, 0x0150,
   1.644 +    0x0250, 0x0350, 0x0450, 0x0550, 0x0650, 0x0750, 0x0850, 0x0950,
   1.645 +    0x0A70, 0x0B70, 0x0C70, 0x0D70, 0x0E70, 0x0F70, 0x1050, 0x1150,
   1.646 +    0x1250, 0x1350, 0x1450, 0x1550, 0x1650, 0x1750, 0x1850, 0x1950,
   1.647 +    0x1A70, 0x1B70, 0x1C70, 0x1D70, 0x1E70, 0x1F70, 0x2050, 0x2150,
   1.648 +    0x2250, 0x2350, 0x2450, 0x2550, 0x2650, 0x2750, 0x2850, 0x2950,
   1.649 +    0x2A70, 0x2B70, 0x2C70, 0x2D70, 0x2E70, 0x2F70, 0x3050, 0x3150,
   1.650 +    0x3250, 0x3350, 0x3450, 0x3550, 0x3650, 0x3750, 0x3850, 0x3950,
   1.651 +    0x3A70, 0x3B70, 0x3C70, 0x3D70, 0x3E70, 0x3F70, 0x4050, 0x4150,
   1.652 +    0x4250, 0x4350, 0x4450, 0x4550, 0x4650, 0x4750, 0x4850, 0x4950,
   1.653 +    0x4A70, 0x4B70, 0x4C70, 0x4D70, 0x4E70, 0x4F70, 0x5050, 0x5150,
   1.654 +    0x5250, 0x5350, 0x5450, 0x5550, 0x5650, 0x5750, 0x5850, 0x5950,
   1.655 +    0x5A70, 0x5B70, 0x5C70, 0x5D70, 0x5E70, 0x5F70, 0x6050, 0x6150,
   1.656 +    0x6250, 0x6350, 0x6450, 0x6550, 0x6650, 0x6750, 0x6850, 0x6950,
   1.657 +    0x6A70, 0x6B70, 0x6C70, 0x6D70, 0x6E70, 0x6F70, 0x7050, 0x7150,
   1.658 +    0x7250, 0x7350, 0x7450, 0x7550, 0x7650, 0x7750, 0x7850, 0x7950,
   1.659 +    0x7A70, 0x7B70, 0x7C70, 0x7D70, 0x7E70, 0x7F70, 0x8050, 0x8150,
   1.660 +    0x8250, 0x8350, 0x8450, 0x8550, 0x8650, 0x8750, 0x8850, 0x8950,
   1.661 +    0x8A70, 0x8B70, 0x8C70, 0x8D70, 0x8E70, 0x8F70, 0x9050, 0x9150,
   1.662 +    0x9250, 0x9350, 0x9450, 0x9550, 0x9650, 0x9750, 0x9850, 0x9950,
   1.663 +  };
   1.664  
   1.665  u8 ZeroTable[] =
   1.666 -{
   1.667 -	0x80, 0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,
   1.668 -	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,
   1.669 -	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,
   1.670 -	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,
   1.671 -	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,
   1.672 -	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,
   1.673 -	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,
   1.674 -	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,
   1.675 -	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,
   1.676 -	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,
   1.677 -	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,
   1.678 -	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,
   1.679 -	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,
   1.680 -	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,
   1.681 -	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,
   1.682 -	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0
   1.683 -};
   1.684 +  {
   1.685 +    0x80, 0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,
   1.686 +    0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,
   1.687 +    0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,
   1.688 +    0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,
   1.689 +    0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,
   1.690 +    0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,
   1.691 +    0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,
   1.692 +    0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,
   1.693 +    0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,
   1.694 +    0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,
   1.695 +    0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,
   1.696 +    0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,
   1.697 +    0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,
   1.698 +    0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,
   1.699 +    0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,
   1.700 +    0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0,	0,	  0
   1.701 +  };
   1.702  
   1.703  #define GBSAVE_GAME_VERSION_1 1
   1.704  #define GBSAVE_GAME_VERSION_2 2
   1.705 @@ -536,81 +536,81 @@
   1.706  
   1.707  int inline gbGetValue(int min, int max, int v)
   1.708  {
   1.709 -	return (int)(min + (float)(max - min) * (2.0 * (v / 31.0) - (v / 31.0) * (v / 31.0)));
   1.710 +  return (int)(min + (float)(max - min) * (2.0 * (v / 31.0) - (v / 31.0) * (v / 31.0)));
   1.711  }
   1.712  
   1.713  void gbGenFilter()
   1.714  {
   1.715 -	for (int r = 0; r < 32; r++)
   1.716 +  for (int r = 0; r < 32; r++)
   1.717 +    {
   1.718 +      for (int g = 0; g < 32; g++)
   1.719  	{
   1.720 -		for (int g = 0; g < 32; g++)
   1.721 -		{
   1.722 -			for (int b = 0; b < 32; b++)
   1.723 -			{
   1.724 -				int nr = gbGetValue(gbGetValue(4, 14, g),
   1.725 -				                    gbGetValue(24, 29, g), r) - 4;
   1.726 -				int ng = gbGetValue(gbGetValue(4 + gbGetValue(0, 5, r),
   1.727 -				                               14 + gbGetValue(0, 3, r), b),
   1.728 -				                    gbGetValue(24 + gbGetValue(0, 3, r),
   1.729 -				                               29 + gbGetValue(0, 1, r), b), g) - 4;
   1.730 -				int nb = gbGetValue(gbGetValue(4 + gbGetValue(0, 5, r),
   1.731 -				                               14 + gbGetValue(0, 3, r), g),
   1.732 -				                    gbGetValue(24 + gbGetValue(0, 3, r),
   1.733 -				                               29 + gbGetValue(0, 1, r), g), b) - 4;
   1.734 -				gbColorFilter[(b << 10) | (g << 5) | r] = (nb << 10) | (ng << 5) | nr;
   1.735 -			}
   1.736 -		}
   1.737 +	  for (int b = 0; b < 32; b++)
   1.738 +	    {
   1.739 +	      int nr = gbGetValue(gbGetValue(4, 14, g),
   1.740 +				  gbGetValue(24, 29, g), r) - 4;
   1.741 +	      int ng = gbGetValue(gbGetValue(4 + gbGetValue(0, 5, r),
   1.742 +					     14 + gbGetValue(0, 3, r), b),
   1.743 +				  gbGetValue(24 + gbGetValue(0, 3, r),
   1.744 +					     29 + gbGetValue(0, 1, r), b), g) - 4;
   1.745 +	      int nb = gbGetValue(gbGetValue(4 + gbGetValue(0, 5, r),
   1.746 +					     14 + gbGetValue(0, 3, r), g),
   1.747 +				  gbGetValue(24 + gbGetValue(0, 3, r),
   1.748 +					     29 + gbGetValue(0, 1, r), g), b) - 4;
   1.749 +	      gbColorFilter[(b << 10) | (g << 5) | r] = (nb << 10) | (ng << 5) | nr;
   1.750 +	    }
   1.751  	}
   1.752 +    }
   1.753  }
   1.754  
   1.755  void gbCopyMemory(u16 d, u16 s, int count)
   1.756  {
   1.757 -	while (count)
   1.758 -	{
   1.759 -		gbWriteMemoryQuick(d, gbReadMemoryQuick(s));
   1.760 -		s++;
   1.761 -		d++;
   1.762 -		count--;
   1.763 -	}
   1.764 +  while (count)
   1.765 +    {
   1.766 +      gbWriteMemoryQuick(d, gbReadMemoryQuick(s));
   1.767 +      s++;
   1.768 +      d++;
   1.769 +      count--;
   1.770 +    }
   1.771  }
   1.772  
   1.773  void gbDoHdma()
   1.774  {
   1.775 -	gbCopyMemory(gbHdmaDestination, gbHdmaSource, 0x10);
   1.776 -
   1.777 -	gbHdmaDestination += 0x10;
   1.778 -	gbHdmaSource	  += 0x10;
   1.779 -
   1.780 -	register_HDMA2 = (register_HDMA2 + 0x10) & 0xFF;
   1.781 -	if (register_HDMA2 == 0x00)
   1.782 -		register_HDMA1++;
   1.783 -
   1.784 -	register_HDMA4 = (register_HDMA4 + 0x10) & 0xFF;
   1.785 -	if (register_HDMA4 == 0x00)
   1.786 -		register_HDMA3++;
   1.787 -
   1.788 -	if (gbHdmaDestination == 0x96b0)
   1.789 -		gbHdmaBytes = gbHdmaBytes;
   1.790 -	gbHdmaBytes -= 0x10;
   1.791 -	register_HDMA5--;
   1.792 -	if (register_HDMA5 == 0xff)
   1.793 -		gbHdmaOn = 0;
   1.794 +  gbCopyMemory(gbHdmaDestination, gbHdmaSource, 0x10);
   1.795 +
   1.796 +  gbHdmaDestination += 0x10;
   1.797 +  gbHdmaSource	  += 0x10;
   1.798 +
   1.799 +  register_HDMA2 = (register_HDMA2 + 0x10) & 0xFF;
   1.800 +  if (register_HDMA2 == 0x00)
   1.801 +    register_HDMA1++;
   1.802 +
   1.803 +  register_HDMA4 = (register_HDMA4 + 0x10) & 0xFF;
   1.804 +  if (register_HDMA4 == 0x00)
   1.805 +    register_HDMA3++;
   1.806 +
   1.807 +  if (gbHdmaDestination == 0x96b0)
   1.808 +    gbHdmaBytes = gbHdmaBytes;
   1.809 +  gbHdmaBytes -= 0x10;
   1.810 +  register_HDMA5--;
   1.811 +  if (register_HDMA5 == 0xff)
   1.812 +    gbHdmaOn = 0;
   1.813  }
   1.814  
   1.815  // fix for Harley and Lego Racers
   1.816  void gbCompareLYToLYC()
   1.817  {
   1.818 -	if (register_LY == register_LYC)
   1.819 -	{
   1.820 -		// mark that we have a match
   1.821 -		register_STAT |= 4;
   1.822 -
   1.823 -		// check if we need an interrupt
   1.824 -		if ((register_STAT & 0x40) && (register_IE & 2))
   1.825 -			gbInterrupt |= 2;
   1.826 -	}
   1.827 -	else   // no match
   1.828 -		register_STAT &= 0xfb;
   1.829 +  if (register_LY == register_LYC)
   1.830 +    {
   1.831 +      // mark that we have a match
   1.832 +      register_STAT |= 4;
   1.833 +
   1.834 +      // check if we need an interrupt
   1.835 +      if ((register_STAT & 0x40) && (register_IE & 2))
   1.836 +	gbInterrupt |= 2;
   1.837 +    }
   1.838 +  else   // no match
   1.839 +    register_STAT &= 0xfb;
   1.840  }
   1.841  
   1.842  // FIXME: horrible kludge to workaround the frame timing bug
   1.843 @@ -618,1971 +618,1971 @@
   1.844  
   1.845  void gbWriteMemoryWrapped(register u16 address, register u8 value)
   1.846  {
   1.847 -	if (address < 0x8000)
   1.848 +  if (address < 0x8000)
   1.849 +    {
   1.850 +#ifndef FINAL_VERSION
   1.851 +      if (memorydebug && (address > 0x3fff || address < 0x2000))
   1.852  	{
   1.853 +	  log("Memory register write %04x=%02x PC=%04x\n",
   1.854 +	      address,
   1.855 +	      value,
   1.856 +	      PC.W);
   1.857 +	}
   1.858 +#endif
   1.859 +      if (mapper)
   1.860 +	(*mapper)(address, value);
   1.861 +      return;
   1.862 +    }
   1.863 +
   1.864 +  if (address < 0xa000)
   1.865 +    {
   1.866 +      gbWriteMemoryQuick(address, value);
   1.867 +      return;
   1.868 +    }
   1.869 +
   1.870 +  if (address < 0xc000)
   1.871 +    {
   1.872  #ifndef FINAL_VERSION
   1.873 -		if (memorydebug && (address > 0x3fff || address < 0x2000))
   1.874 -		{
   1.875 -			log("Memory register write %04x=%02x PC=%04x\n",
   1.876 -			    address,
   1.877 -			    value,
   1.878 -			    PC.W);
   1.879 -		}
   1.880 +      if (memorydebug)
   1.881 +	{
   1.882 +	  log("Memory register write %04x=%02x PC=%04x\n",
   1.883 +	      address,
   1.884 +	      value,
   1.885 +	      PC.W);
   1.886 +	}
   1.887  #endif
   1.888 -		if (mapper)
   1.889 -			(*mapper)(address, value);
   1.890 -		return;
   1.891 +
   1.892 +      if (mapper)
   1.893 +	(*mapperRAM)(address, value);
   1.894 +      return;
   1.895 +    }
   1.896 +
   1.897 +  if (address < 0xfe00)
   1.898 +    {
   1.899 +      gbWriteMemoryQuick(address, value);
   1.900 +      return;
   1.901 +    }
   1.902 +
   1.903 +  if (address < 0xff00)
   1.904 +    {
   1.905 +      gbMemory[address] = value;
   1.906 +      return;
   1.907 +    }
   1.908 +
   1.909 +  switch (address & 0x00ff)
   1.910 +    {
   1.911 +    case 0x00:
   1.912 +      {
   1.913 +	gbMemory[0xff00] = ((gbMemory[0xff00] & 0xcf) |
   1.914 +			    (value & 0x30));
   1.915 +	if (gbSgbMode)
   1.916 +	  {
   1.917 +	    gbSgbDoBitTransfer(value);
   1.918 +	  }
   1.919 +
   1.920 +	return;
   1.921 +      }
   1.922 +
   1.923 +    case 0x01:
   1.924 +      {
   1.925 +	gbMemory[0xff01] = value;
   1.926 +	return;
   1.927 +      }
   1.928 +
   1.929 +      // serial control
   1.930 +    case 0x02:
   1.931 +      {
   1.932 +	gbSerialOn		 = (value & 0x80);
   1.933 +	gbMemory[0xff02] = value;
   1.934 +	if (gbSerialOn)
   1.935 +	  {
   1.936 +	    gbSerialTicks = GBSERIAL_CLOCK_TICKS;
   1.937 +#ifdef LINK_EMULATION
   1.938 +	    if (linkConnected)
   1.939 +	      {
   1.940 +		if (value & 1)
   1.941 +		  {
   1.942 +		    linkSendByte(0x100 | gbMemory[0xFF01]);
   1.943 +		    Sleep(5);
   1.944 +		  }
   1.945 +	      }
   1.946 +#endif
   1.947 +	  }
   1.948 +
   1.949 +	gbSerialBits = 0;
   1.950 +	return;
   1.951 +      }
   1.952 +
   1.953 +      // DIV register resets on any write
   1.954 +    case 0x04:
   1.955 +      {
   1.956 +	register_DIV = 0;
   1.957 +	return;
   1.958 +      }
   1.959 +    case 0x05:
   1.960 +      register_TIMA = value;
   1.961 +      return;
   1.962 +
   1.963 +    case 0x06:
   1.964 +      register_TMA = value;
   1.965 +      return;
   1.966 +
   1.967 +      // TIMER control
   1.968 +    case 0x07:
   1.969 +      {
   1.970 +	register_TAC = value;
   1.971 +
   1.972 +	gbTimerOn	= (value & 4);
   1.973 +	gbTimerMode = value & 3;
   1.974 +	//    register_TIMA = register_TMA;
   1.975 +	switch (gbTimerMode)
   1.976 +	  {
   1.977 +	  case 0:
   1.978 +	    gbTimerClockTicks = gbTimerTicks = GBTIMER_MODE_0_CLOCK_TICKS;
   1.979 +	    break;
   1.980 +	  case 1:
   1.981 +	    gbTimerClockTicks = gbTimerTicks = GBTIMER_MODE_1_CLOCK_TICKS;
   1.982 +	    break;
   1.983 +	  case 2:
   1.984 +	    gbTimerClockTicks = gbTimerTicks = GBTIMER_MODE_2_CLOCK_TICKS;
   1.985 +	    break;
   1.986 +	  case 3:
   1.987 +	    gbTimerClockTicks = gbTimerTicks = GBTIMER_MODE_3_CLOCK_TICKS;
   1.988 +	    break;
   1.989 +	  }
   1.990 +	return;
   1.991 +      }
   1.992 +
   1.993 +    case 0x0f:
   1.994 +      {
   1.995 +	register_IF = value;
   1.996 +	gbInterrupt = value;
   1.997 +	return;
   1.998 +      }
   1.999 +
  1.1000 +    case 0x10:
  1.1001 +    case 0x11:
  1.1002 +    case 0x12:
  1.1003 +    case 0x13:
  1.1004 +    case 0x14:
  1.1005 +    case 0x15:
  1.1006 +    case 0x16:
  1.1007 +    case 0x17:
  1.1008 +    case 0x18:
  1.1009 +    case 0x19:
  1.1010 +    case 0x1a:
  1.1011 +    case 0x1b:
  1.1012 +    case 0x1c:
  1.1013 +    case 0x1d:
  1.1014 +    case 0x1e:
  1.1015 +    case 0x1f:
  1.1016 +    case 0x20:
  1.1017 +    case 0x21:
  1.1018 +    case 0x22:
  1.1019 +    case 0x23:
  1.1020 +    case 0x24:
  1.1021 +    case 0x25:
  1.1022 +    case 0x26:
  1.1023 +      {
  1.1024 +	SOUND_EVENT(address, value);
  1.1025 +	return;
  1.1026 +      }
  1.1027 +    case 0x40:
  1.1028 +      {
  1.1029 +	int lcdChange = (register_LCDC & 0x80) ^ (value & 0x80);
  1.1030 +
  1.1031 +	if (lcdChange)
  1.1032 +	  {
  1.1033 +	    if (value & 0x80)
  1.1034 +	      {
  1.1035 +		gbLcdTicks	   = GBLCD_MODE_1_CLOCK_TICKS;
  1.1036 +		gbLcdMode	   = 0;
  1.1037 +		register_STAT &= 0xfc;
  1.1038 +		register_LY	   = 0x00;
  1.1039 +		// FIXME: horrible workaround
  1.1040 +		if (gbNullInputHackTempEnabled && !useOldFrameTiming)
  1.1041 +		  memcpy(gbJoymask, s_gbJoymask, sizeof(gbJoymask));
  1.1042 +	      }
  1.1043 +	    else
  1.1044 +	      {
  1.1045 +		gbLcdTicks	   = 0;
  1.1046 +		gbLcdMode	   = 0;
  1.1047 +		register_STAT &= 0xfc;
  1.1048 +		register_LY	   = 0x00;
  1.1049 +		// FIXME: horrible workaround
  1.1050 +		memcpy(s_gbJoymask, gbJoymask, sizeof(gbJoymask));
  1.1051 +		if (gbNullInputHackTempEnabled && !useOldFrameTiming)
  1.1052 +		  memset(gbJoymask, 0, sizeof(gbJoymask));
  1.1053 +	      }
  1.1054 +	    //      compareLYToLYC();
  1.1055 +	  }
  1.1056 +	// don't draw the window if it was not enabled and not being drawn before
  1.1057 +	if (!(register_LCDC & 0x20) && (value & 0x20) && gbWindowLine == -1 &&
  1.1058 +	    register_LY > register_WY)
  1.1059 +	  gbWindowLine = 144;
  1.1060 +
  1.1061 +	register_LCDC = value;
  1.1062 +
  1.1063 +	return;
  1.1064 +      }
  1.1065 +
  1.1066 +      // STAT
  1.1067 +    case 0x41:
  1.1068 +      {
  1.1069 +	//register_STAT = (register_STAT & 0x87) |
  1.1070 +	//      (value & 0x7c);
  1.1071 +	register_STAT = (value & 0xf8) | (register_STAT & 0x07);     // fix ?
  1.1072 +	// GB bug from Devrs FAQ
  1.1073 +	if (!gbCgbMode && (register_LCDC & 0x80) && gbLcdMode < 2)
  1.1074 +	  gbInterrupt |= 2;
  1.1075 +	return;
  1.1076 +      }
  1.1077 +
  1.1078 +      // SCY
  1.1079 +    case 0x42:
  1.1080 +      {
  1.1081 +	register_SCY = value;
  1.1082 +	return;
  1.1083 +      }
  1.1084 +
  1.1085 +      // SCX
  1.1086 +    case 0x43:
  1.1087 +      {
  1.1088 +	register_SCX = value;
  1.1089 +	return;
  1.1090 +      }
  1.1091 +
  1.1092 +      // LY
  1.1093 +    case 0x44:
  1.1094 +      {
  1.1095 +	// read only
  1.1096 +	return;
  1.1097 +      }
  1.1098 +
  1.1099 +      // LYC
  1.1100 +    case 0x45:
  1.1101 +      {
  1.1102 +	register_LYC = value;
  1.1103 +	if ((register_LCDC & 0x80))
  1.1104 +	  {
  1.1105 +	    gbCompareLYToLYC();
  1.1106 +	  }
  1.1107 +	return;
  1.1108 +      }
  1.1109 +
  1.1110 +      // DMA!
  1.1111 +    case 0x46:
  1.1112 +      {
  1.1113 +	int source = value * 0x0100;
  1.1114 +
  1.1115 +	gbCopyMemory(0xfe00,
  1.1116 +		     source,
  1.1117 +		     0xa0);
  1.1118 +	register_DMA = value;
  1.1119 +	return;
  1.1120 +      }
  1.1121 +
  1.1122 +      // BGP
  1.1123 +    case 0x47:
  1.1124 +      {
  1.1125 +	gbBgp[0] = value & 0x03;
  1.1126 +	gbBgp[1] = (value & 0x0c) >> 2;
  1.1127 +	gbBgp[2] = (value & 0x30) >> 4;
  1.1128 +	gbBgp[3] = (value & 0xc0) >> 6;
  1.1129 +	break;
  1.1130 +      }
  1.1131 +
  1.1132 +      // OBP0
  1.1133 +    case 0x48:
  1.1134 +      {
  1.1135 +	gbObp0[0] = value & 0x03;
  1.1136 +	gbObp0[1] = (value & 0x0c) >> 2;
  1.1137 +	gbObp0[2] = (value & 0x30) >> 4;
  1.1138 +	gbObp0[3] = (value & 0xc0) >> 6;
  1.1139 +	break;
  1.1140 +      }
  1.1141 +
  1.1142 +      // OBP1
  1.1143 +    case 0x49:
  1.1144 +      {
  1.1145 +	gbObp1[0] = value & 0x03;
  1.1146 +	gbObp1[1] = (value & 0x0c) >> 2;
  1.1147 +	gbObp1[2] = (value & 0x30) >> 4;
  1.1148 +	gbObp1[3] = (value & 0xc0) >> 6;
  1.1149 +	break;
  1.1150 +      }
  1.1151 +
  1.1152 +    case 0x4a:
  1.1153 +      register_WY = value;
  1.1154 +      return;
  1.1155 +
  1.1156 +    case 0x4b:
  1.1157 +      register_WX = value;
  1.1158 +      return;
  1.1159 +
  1.1160 +      // KEY1
  1.1161 +    case 0x4d:
  1.1162 +      {
  1.1163 +	if (gbCgbMode)
  1.1164 +	  {
  1.1165 +	    gbMemory[0xff4d] = (gbMemory[0xff4d] & 0x80) | (value & 1);
  1.1166 +	    return;
  1.1167 +	  }
  1.1168 +	break;
  1.1169 +      }
  1.1170 +
  1.1171 +      // VBK
  1.1172 +    case 0x4f:
  1.1173 +      {
  1.1174 +	if (gbCgbMode)
  1.1175 +	  {
  1.1176 +	    value = value & 1;
  1.1177 +	    if (value == gbVramBank)
  1.1178 +	      return;
  1.1179 +
  1.1180 +	    int vramAddress = value * 0x2000;
  1.1181 +	    gbMemoryMap[0x08] = &gbVram[vramAddress];
  1.1182 +	    gbMemoryMap[0x09] = &gbVram[vramAddress + 0x1000];
  1.1183 +
  1.1184 +	    gbVramBank	 = value;
  1.1185 +	    register_VBK = value;
  1.1186 +	  }
  1.1187 +	return;
  1.1188 +	break;
  1.1189 +      }
  1.1190 +
  1.1191 +      // HDMA1
  1.1192 +    case 0x51:
  1.1193 +      {
  1.1194 +	if (gbCgbMode)
  1.1195 +	  {
  1.1196 +	    if (value > 0x7f && value < 0xa0)
  1.1197 +	      value = 0;
  1.1198 +
  1.1199 +	    gbHdmaSource = (value << 8) | (register_HDMA2 & 0xf0);
  1.1200 +
  1.1201 +	    register_HDMA1 = value;
  1.1202 +	    return;
  1.1203 +	  }
  1.1204 +	break;
  1.1205 +      }
  1.1206 +
  1.1207 +      // HDMA2
  1.1208 +    case 0x52:
  1.1209 +      {
  1.1210 +	if (gbCgbMode)
  1.1211 +	  {
  1.1212 +	    value = value & 0xf0;
  1.1213 +
  1.1214 +	    gbHdmaSource = (register_HDMA1 << 8) | (value);
  1.1215 +
  1.1216 +	    register_HDMA2 = value;
  1.1217 +	    return;
  1.1218 +	  }
  1.1219 +	break;
  1.1220 +      }
  1.1221 +
  1.1222 +      // HDMA3
  1.1223 +    case 0x53:
  1.1224 +      {
  1.1225 +	if (gbCgbMode)
  1.1226 +	  {
  1.1227 +	    value = value & 0x1f;
  1.1228 +	    gbHdmaDestination  = (value << 8) | (register_HDMA4 & 0xf0);
  1.1229 +	    gbHdmaDestination += 0x8000;
  1.1230 +	    register_HDMA3	   = value;
  1.1231 +	    return;
  1.1232 +	  }
  1.1233 +	break;
  1.1234 +      }
  1.1235 +
  1.1236 +      // HDMA4
  1.1237 +    case 0x54:
  1.1238 +      {
  1.1239 +	if (gbCgbMode)
  1.1240 +	  {
  1.1241 +	    value = value & 0xf0;
  1.1242 +	    gbHdmaDestination  = ((register_HDMA3 & 0x1f) << 8) | value;
  1.1243 +	    gbHdmaDestination += 0x8000;
  1.1244 +	    register_HDMA4	   = value;
  1.1245 +	    return;
  1.1246 +	  }
  1.1247 +	break;
  1.1248 +      }
  1.1249 +
  1.1250 +      // HDMA5
  1.1251 +    case 0x55:
  1.1252 +      {
  1.1253 +	if (gbCgbMode)
  1.1254 +	  {
  1.1255 +	    gbHdmaBytes = 16 + (value & 0x7f) * 16;
  1.1256 +	    if (gbHdmaOn)
  1.1257 +	      {
  1.1258 +		if (value & 0x80)
  1.1259 +		  {
  1.1260 +		    register_HDMA5 = (value & 0x7f);
  1.1261 +		  }
  1.1262 +		else
  1.1263 +		  {
  1.1264 +		    register_HDMA5 = 0xff;
  1.1265 +		    gbHdmaOn	   = 0;
  1.1266 +		  }
  1.1267 +	      }
  1.1268 +	    else
  1.1269 +	      {
  1.1270 +		if (value & 0x80)
  1.1271 +		  {
  1.1272 +		    gbHdmaOn	   = 1;
  1.1273 +		    register_HDMA5 = value & 0x7f;
  1.1274 +		    if (gbLcdMode == 0)
  1.1275 +		      gbDoHdma();
  1.1276 +		  }
  1.1277 +		else
  1.1278 +		  {
  1.1279 +		    // we need to take the time it takes to complete the transfer into
  1.1280 +		    // account... according to GB DEV FAQs, the setup time is the same
  1.1281 +		    // for single and double speed, but the actual transfer takes the
  1.1282 +		    // same time // (is that a typo?)
  1.1283 +		    switch (gbDMASpeedVersion)
  1.1284 +		      {
  1.1285 +		      case 1:     // I believe this is more correct
  1.1286 +			// the lower 7 bits of FF55 specify the Transfer Length (divided by 16, minus 1)
  1.1287 +			// and we make gbDmaTicks twice as many cycles at double speed to make the transfer take the same time
  1.1288 +			if (gbSpeed)
  1.1289 +			  gbDmaTicks = 16 * ((value & 0x7f) + 1);
  1.1290 +			else
  1.1291 +			  gbDmaTicks = 8 * ((value & 0x7f) + 1);
  1.1292 +			break;
  1.1293 +		      case 0:     // here for backward compatibility
  1.1294 +			// I think this was a guess that approximates the above in most but not all games
  1.1295 +			if (gbSpeed)
  1.1296 +			  gbDmaTicks = 231 + 16 * (value & 0x7f);
  1.1297 +			else
  1.1298 +			  gbDmaTicks = 231 + 8 * (value & 0x7f);
  1.1299 +			break;
  1.1300 +		      default:     // shouldn't happen
  1.1301 +			//assert(0);
  1.1302 +			break;
  1.1303 +		      }
  1.1304 +		    gbCopyMemory(gbHdmaDestination, gbHdmaSource, gbHdmaBytes);
  1.1305 +		    gbHdmaDestination += gbHdmaBytes;
  1.1306 +		    gbHdmaSource	  += gbHdmaBytes;
  1.1307 +
  1.1308 +		    register_HDMA3 = ((gbHdmaDestination - 0x8000) >> 8) & 0x1f;
  1.1309 +		    register_HDMA4 = gbHdmaDestination & 0xf0;
  1.1310 +		    register_HDMA1 = (gbHdmaSource >> 8) & 0xff;
  1.1311 +		    register_HDMA2 = gbHdmaSource & 0xf0;
  1.1312 +		  }
  1.1313 +	      }
  1.1314 +	    return;
  1.1315 +	  }
  1.1316 +	break;
  1.1317 +      }
  1.1318 +
  1.1319 +      // BCPS
  1.1320 +    case 0x68:
  1.1321 +      {
  1.1322 +	if (gbCgbMode)
  1.1323 +	  {
  1.1324 +	    int paletteIndex = (value & 0x3f) >> 1;
  1.1325 +	    int paletteHiLo	 = (value & 0x01);
  1.1326 +
  1.1327 +	    gbMemory[0xff68] = value;
  1.1328 +	    gbMemory[0xff69] = (paletteHiLo ?
  1.1329 +				(gbPalette[paletteIndex] >> 8) :
  1.1330 +				(gbPalette[paletteIndex] & 0x00ff));
  1.1331 +	    return;
  1.1332 +	  }
  1.1333 +	break;
  1.1334 +      }
  1.1335 +
  1.1336 +      // BCPD
  1.1337 +    case 0x69:
  1.1338 +      {
  1.1339 +	if (gbCgbMode)
  1.1340 +	  {
  1.1341 +	    int v = gbMemory[0xff68];
  1.1342 +	    int paletteIndex = (v & 0x3f) >> 1;
  1.1343 +	    int paletteHiLo	 = (v & 0x01);
  1.1344 +	    gbMemory[0xff69]		= value;
  1.1345 +	    gbPalette[paletteIndex] = (paletteHiLo ?
  1.1346 +				       ((value << 8) | (gbPalette[paletteIndex] & 0xff)) :
  1.1347 +				       ((gbPalette[paletteIndex] & 0xff00) | (value))) & 0x7fff;
  1.1348 +
  1.1349 +	    if (gbMemory[0xff68] & 0x80)
  1.1350 +	      {
  1.1351 +		int index = ((gbMemory[0xff68] & 0x3f) + 1) & 0x3f;
  1.1352 +
  1.1353 +		gbMemory[0xff68] = (gbMemory[0xff68] & 0x80) | index;
  1.1354 +
  1.1355 +		gbMemory[0xff69] = (index & 1 ?
  1.1356 +				    (gbPalette[index >> 1] >> 8) :
  1.1357 +				    (gbPalette[index >> 1] & 0x00ff));
  1.1358 +	      }
  1.1359 +	    return;
  1.1360 +	  }
  1.1361 +	break;
  1.1362 +      }
  1.1363 +
  1.1364 +      // OCPS
  1.1365 +    case 0x6a:
  1.1366 +      {
  1.1367 +	if (gbCgbMode)
  1.1368 +	  {
  1.1369 +	    int paletteIndex = (value & 0x3f) >> 1;
  1.1370 +	    int paletteHiLo	 = (value & 0x01);
  1.1371 +
  1.1372 +	    paletteIndex += 32;
  1.1373 +
  1.1374 +	    gbMemory[0xff6a] = value;
  1.1375 +	    gbMemory[0xff6b] = (paletteHiLo ?
  1.1376 +				(gbPalette[paletteIndex] >> 8) :
  1.1377 +				(gbPalette[paletteIndex] & 0x00ff));
  1.1378 +	    return;
  1.1379 +	  }
  1.1380 +	break;
  1.1381 +      }
  1.1382 +
  1.1383 +      // OCPD
  1.1384 +    case 0x6b:
  1.1385 +      {
  1.1386 +	if (gbCgbMode)
  1.1387 +	  {
  1.1388 +	    int v = gbMemory[0xff6a];
  1.1389 +	    int paletteIndex = (v & 0x3f) >> 1;
  1.1390 +	    int paletteHiLo	 = (v & 0x01);
  1.1391 +
  1.1392 +	    paletteIndex += 32;
  1.1393 +
  1.1394 +	    gbMemory[0xff6b]		= value;
  1.1395 +	    gbPalette[paletteIndex] = (paletteHiLo ?
  1.1396 +				       ((value << 8) | (gbPalette[paletteIndex] & 0xff)) :
  1.1397 +				       ((gbPalette[paletteIndex] & 0xff00) | (value))) & 0x7fff;
  1.1398 +	    if (gbMemory[0xff6a] & 0x80)
  1.1399 +	      {
  1.1400 +		int index = ((gbMemory[0xff6a] & 0x3f) + 1) & 0x3f;
  1.1401 +
  1.1402 +		gbMemory[0xff6a] = (gbMemory[0xff6a] & 0x80) | index;
  1.1403 +
  1.1404 +		gbMemory[0xff6b] = (index & 1 ?
  1.1405 +				    (gbPalette[(index >> 1) + 32] >> 8) :
  1.1406 +				    (gbPalette[(index >> 1) + 32] & 0x00ff));
  1.1407 +	      }
  1.1408 +	    return;
  1.1409 +	  }
  1.1410 +	break;
  1.1411 +      }
  1.1412 +
  1.1413 +      // SVBK
  1.1414 +    case 0x70:
  1.1415 +      {
  1.1416 +	if (gbCgbMode)
  1.1417 +	  {
  1.1418 +	    value = value & 7;
  1.1419 +
  1.1420 +	    int bank = value;
  1.1421 +	    if (value == 0)
  1.1422 +	      bank = 1;
  1.1423 +
  1.1424 +	    if (bank == gbWramBank)
  1.1425 +	      return;
  1.1426 +
  1.1427 +	    int wramAddress = bank * 0x1000;
  1.1428 +	    gbMemoryMap[0x0d] = &gbWram[wramAddress];
  1.1429 +
  1.1430 +	    gbWramBank	  = bank;
  1.1431 +	    register_SVBK = value;
  1.1432 +	    return;
  1.1433 +	  }
  1.1434 +	break;
  1.1435 +      }
  1.1436 +
  1.1437 +    case 0xff:
  1.1438 +      {
  1.1439 +	register_IE	 = value;
  1.1440 +	register_IF &= value;
  1.1441 +	return;
  1.1442 +      }
  1.1443 +    }
  1.1444 +
  1.1445 +  gbWriteMemoryQuick(address, value);
  1.1446 +}
  1.1447 +
  1.1448 +u8 gbReadOpcode(register u16 address)
  1.1449 +{
  1.1450 +  if (gbCheatMap[address])
  1.1451 +    return gbCheatRead(address);
  1.1452 +
  1.1453 +  // the following fix does more than Echo RAM fix, anyway...
  1.1454 +  switch (gbEchoRAMFixOn ? (address >> 12) & 0x000f : address & 0xf000)
  1.1455 +    {
  1.1456 +    case 0x0a:
  1.1457 +    case 0x0b:
  1.1458 +      if (mapperReadRAM)
  1.1459 +	return mapperReadRAM(address);
  1.1460 +      break;
  1.1461 +    case 0x0f:
  1.1462 +      if (address > 0xff00)
  1.1463 +	{
  1.1464 +	  switch (address & 0x00ff)
  1.1465 +	    {
  1.1466 +	    case 0x04:
  1.1467 +	      return register_DIV;
  1.1468 +	    case 0x05:
  1.1469 +	      return register_TIMA;
  1.1470 +	    case 0x06:
  1.1471 +	      return register_TMA;
  1.1472 +	    case 0x07:
  1.1473 +	      return (0xf8 | register_TAC);
  1.1474 +	    case 0x0f:
  1.1475 +	      return (0xe0 | register_IF);
  1.1476 +	    case 0x40:
  1.1477 +	      return register_LCDC;
  1.1478 +	    case 0x41:
  1.1479 +	      return (0x80 | register_STAT);
  1.1480 +	    case 0x42:
  1.1481 +	      return register_SCY;
  1.1482 +	    case 0x43:
  1.1483 +	      return register_SCX;
  1.1484 +	    case 0x44:
  1.1485 +	      return register_LY;
  1.1486 +	    case 0x45:
  1.1487 +	      return register_LYC;
  1.1488 +	    case 0x46:
  1.1489 +	      return register_DMA;
  1.1490 +	    case 0x4a:
  1.1491 +	      return register_WY;
  1.1492 +	    case 0x4b:
  1.1493 +	      return register_WX;
  1.1494 +	    case 0x4f:
  1.1495 +	      return (0xfe | register_VBK);
  1.1496 +	    case 0x51:
  1.1497 +	      return register_HDMA1;
  1.1498 +	    case 0x52:
  1.1499 +	      return register_HDMA2;
  1.1500 +	    case 0x53:
  1.1501 +	      return register_HDMA3;
  1.1502 +	    case 0x54:
  1.1503 +	      return register_HDMA4;
  1.1504 +	    case 0x55:
  1.1505 +	      return register_HDMA5;
  1.1506 +	    case 0x70:
  1.1507 +	      return (0xf8 | register_SVBK);
  1.1508 +	    case 0xff:
  1.1509 +	      return register_IE;
  1.1510 +	    }
  1.1511  	}
  1.1512 -
  1.1513 -	if (address < 0xa000)
  1.1514 +      break;
  1.1515 +    }
  1.1516 +  return gbReadMemoryQuick(address);
  1.1517 +}
  1.1518 +
  1.1519 +void gbWriteMemory(register u16 address, register u8 value)
  1.1520 +{
  1.1521 +  gbWriteMemoryWrapped(address, value);
  1.1522 +  CallRegisteredLuaMemHook(address, 1, value, LUAMEMHOOK_WRITE);
  1.1523 +}
  1.1524 +
  1.1525 +u8 gbReadMemory(register u16 address)
  1.1526 +{
  1.1527 +  if (gbCheatMap[address])
  1.1528 +    return gbCheatRead(address);
  1.1529 +
  1.1530 +  if (address < 0xa000)
  1.1531 +    return gbReadMemoryQuick(address);
  1.1532 +
  1.1533 +  if (address < 0xc000)
  1.1534 +    {
  1.1535 +#ifndef FINAL_VERSION
  1.1536 +      if (memorydebug)
  1.1537  	{
  1.1538 -		gbWriteMemoryQuick(address, value);
  1.1539 -		return;
  1.1540 +	  log("Memory register read %04x PC=%04x\n",
  1.1541 +	      address,
  1.1542 +	      PC.W);
  1.1543  	}
  1.1544 -
  1.1545 -	if (address < 0xc000)
  1.1546 -	{
  1.1547 -#ifndef FINAL_VERSION
  1.1548 -		if (memorydebug)
  1.1549 -		{
  1.1550 -			log("Memory register write %04x=%02x PC=%04x\n",
  1.1551 -			    address,
  1.1552 -			    value,
  1.1553 -			    PC.W);
  1.1554 -		}
  1.1555  #endif
  1.1556  
  1.1557 -		if (mapper)
  1.1558 -			(*mapperRAM)(address, value);
  1.1559 -		return;
  1.1560 -	}
  1.1561 -
  1.1562 -	if (address < 0xfe00)
  1.1563 -	{
  1.1564 -		gbWriteMemoryQuick(address, value);
  1.1565 -		return;
  1.1566 -	}
  1.1567 -
  1.1568 -	if (address < 0xff00)
  1.1569 -	{
  1.1570 -		gbMemory[address] = value;
  1.1571 -		return;
  1.1572 -	}
  1.1573 -
  1.1574 -	switch (address & 0x00ff)
  1.1575 +      if (mapperReadRAM)
  1.1576 +	return mapperReadRAM(address);
  1.1577 +      return gbReadMemoryQuick(address);
  1.1578 +    }
  1.1579 +
  1.1580 +  if (address >= 0xff00)
  1.1581 +    {
  1.1582 +      switch (address & 0x00ff)
  1.1583  	{
  1.1584  	case 0x00:
  1.1585 -	{
  1.1586 -		gbMemory[0xff00] = ((gbMemory[0xff00] & 0xcf) |
  1.1587 -		                    (value & 0x30));
  1.1588 -		if (gbSgbMode)
  1.1589 -		{
  1.1590 -			gbSgbDoBitTransfer(value);
  1.1591 -		}
  1.1592 -
  1.1593 -		return;
  1.1594 +	  {
  1.1595 +	    if (gbSgbMode)
  1.1596 +	      {
  1.1597 +		gbSgbReadingController |= 4;
  1.1598 +		gbSgbResetPacketState();
  1.1599 +	      }
  1.1600 +
  1.1601 +	    int b = gbMemory[0xff00];
  1.1602 +
  1.1603 +	    if ((b & 0x30) == 0x20)
  1.1604 +	      {
  1.1605 +		b &= 0xf0;
  1.1606 +
  1.1607 +		int joy = 0;
  1.1608 +		if (gbSgbMode && gbSgbMultiplayer)
  1.1609 +		  {
  1.1610 +		    switch (gbSgbNextController)
  1.1611 +		      {
  1.1612 +		      case 0x0f:
  1.1613 +			joy = 0;
  1.1614 +			break;
  1.1615 +		      case 0x0e:
  1.1616 +			joy = 1;
  1.1617 +			break;
  1.1618 +		      case 0x0d:
  1.1619 +			joy = 2;
  1.1620 +			break;
  1.1621 +		      case 0x0c:
  1.1622 +			joy = 3;
  1.1623 +			break;
  1.1624 +		      default:
  1.1625 +			joy = 0;
  1.1626 +		      }
  1.1627 +		  }
  1.1628 +		int joystate = gbJoymask[joy];
  1.1629 +		if (!(joystate & 128))
  1.1630 +		  b |= 0x08;
  1.1631 +		if (!(joystate & 64))
  1.1632 +		  b |= 0x04;
  1.1633 +		if (!(joystate & 32))
  1.1634 +		  b |= 0x02;
  1.1635 +		if (!(joystate & 16))
  1.1636 +		  b |= 0x01;
  1.1637 +
  1.1638 +		gbMemory[0xff00] = b;
  1.1639 +	      }
  1.1640 +	    else if ((b & 0x30) == 0x10)
  1.1641 +	      {
  1.1642 +		b &= 0xf0;
  1.1643 +
  1.1644 +		int joy = 0;
  1.1645 +		if (gbSgbMode && gbSgbMultiplayer)
  1.1646 +		  {
  1.1647 +		    switch (gbSgbNextController)
  1.1648 +		      {
  1.1649 +		      case 0x0f:
  1.1650 +			joy = 0;
  1.1651 +			break;
  1.1652 +		      case 0x0e:
  1.1653 +			joy = 1;
  1.1654 +			break;
  1.1655 +		      case 0x0d:
  1.1656 +			joy = 2;
  1.1657 +			break;
  1.1658 +		      case 0x0c:
  1.1659 +			joy = 3;
  1.1660 +			break;
  1.1661 +		      default:
  1.1662 +			joy = 0;
  1.1663 +		      }
  1.1664 +		  }
  1.1665 +		int joystate = gbJoymask[joy];
  1.1666 +		if (!(joystate & 8))
  1.1667 +		  b |= 0x08;
  1.1668 +		if (!(joystate & 4))
  1.1669 +		  b |= 0x04;
  1.1670 +		if (!(joystate & 2))
  1.1671 +		  b |= 0x02;
  1.1672 +		if (!(joystate & 1))
  1.1673 +		  b |= 0x01;
  1.1674 +
  1.1675 +		gbMemory[0xff00] = b;
  1.1676 +	      }
  1.1677 +	    else
  1.1678 +	      {
  1.1679 +		if (gbSgbMode && gbSgbMultiplayer)
  1.1680 +		  {
  1.1681 +		    gbMemory[0xff00] = 0xf0 | gbSgbNextController;
  1.1682 +		  }
  1.1683 +		else
  1.1684 +		  {
  1.1685 +		    gbMemory[0xff00] = 0xff;
  1.1686 +		  }
  1.1687 +	      }
  1.1688 +	  }
  1.1689 +	  GBSystemCounters.lagged = false;
  1.1690 +	  return gbMemory[0xff00];
  1.1691 +	  break;
  1.1692 +	case 0x01:
  1.1693 +	  return gbMemory[0xff01];
  1.1694 +	case 0x04:
  1.1695 +	  return register_DIV;
  1.1696 +	case 0x05:
  1.1697 +	  return register_TIMA;
  1.1698 +	case 0x06:
  1.1699 +	  return register_TMA;
  1.1700 +	case 0x07:
  1.1701 +	  return (0xf8 | register_TAC);
  1.1702 +	case 0x0f:
  1.1703 +	  return (0xe0 | register_IF);
  1.1704 +	case 0x40:
  1.1705 +	  return register_LCDC;
  1.1706 +	case 0x41:
  1.1707 +	  return (0x80 | register_STAT);
  1.1708 +	case 0x42:
  1.1709 +	  return register_SCY;
  1.1710 +	case 0x43:
  1.1711 +	  return register_SCX;
  1.1712 +	case 0x44:
  1.1713 +	  return register_LY;
  1.1714 +	case 0x45:
  1.1715 +	  return register_LYC;
  1.1716 +	case 0x46:
  1.1717 +	  return register_DMA;
  1.1718 +	case 0x4a:
  1.1719 +	  return register_WY;
  1.1720 +	case 0x4b:
  1.1721 +	  return register_WX;
  1.1722 +	case 0x4f:
  1.1723 +	  return (0xfe | register_VBK);
  1.1724 +	case 0x51:
  1.1725 +	  return register_HDMA1;
  1.1726 +	case 0x52:
  1.1727 +	  return register_HDMA2;
  1.1728 +	case 0x53:
  1.1729 +	  return register_HDMA3;
  1.1730 +	case 0x54:
  1.1731 +	  return register_HDMA4;
  1.1732 +	case 0x55:
  1.1733 +	  return register_HDMA5;
  1.1734 +	case 0x70:
  1.1735 +	  return (0xf8 | register_SVBK);
  1.1736 +	case 0xff:
  1.1737 +	  return register_IE;
  1.1738  	}
  1.1739 -
  1.1740 -	case 0x01:
  1.1741 -	{
  1.1742 -		gbMemory[0xff01] = value;
  1.1743 -		return;
  1.1744 -	}
  1.1745 -
  1.1746 -	// serial control
  1.1747 -	case 0x02:
  1.1748 -	{
  1.1749 -		gbSerialOn		 = (value & 0x80);
  1.1750 -		gbMemory[0xff02] = value;
  1.1751 -		if (gbSerialOn)
  1.1752 -		{
  1.1753 -			gbSerialTicks = GBSERIAL_CLOCK_TICKS;
  1.1754 -#ifdef LINK_EMULATION
  1.1755 -			if (linkConnected)
  1.1756 -			{
  1.1757 -				if (value & 1)
  1.1758 -				{
  1.1759 -					linkSendByte(0x100 | gbMemory[0xFF01]);
  1.1760 -					Sleep(5);
  1.1761 -				}
  1.1762 -			}
  1.1763 -#endif
  1.1764 -		}
  1.1765 -
  1.1766 -		gbSerialBits = 0;
  1.1767 -		return;
  1.1768 -	}
  1.1769 -
  1.1770 -	// DIV register resets on any write
  1.1771 -	case 0x04:
  1.1772 -	{
  1.1773 -		register_DIV = 0;
  1.1774 -		return;
  1.1775 -	}
  1.1776 -	case 0x05:
  1.1777 -		register_TIMA = value;
  1.1778 -		return;
  1.1779 -
  1.1780 -	case 0x06:
  1.1781 -		register_TMA = value;
  1.1782 -		return;
  1.1783 -
  1.1784 -	// TIMER control
  1.1785 -	case 0x07:
  1.1786 -	{
  1.1787 -		register_TAC = value;
  1.1788 -
  1.1789 -		gbTimerOn	= (value & 4);
  1.1790 -		gbTimerMode = value & 3;
  1.1791 -		//    register_TIMA = register_TMA;
  1.1792 -		switch (gbTimerMode)
  1.1793 -		{
  1.1794 -		case 0:
  1.1795 -			gbTimerClockTicks = gbTimerTicks = GBTIMER_MODE_0_CLOCK_TICKS;
  1.1796 -			break;
  1.1797 -		case 1:
  1.1798 -			gbTimerClockTicks = gbTimerTicks = GBTIMER_MODE_1_CLOCK_TICKS;
  1.1799 -			break;
  1.1800 -		case 2:
  1.1801 -			gbTimerClockTicks = gbTimerTicks = GBTIMER_MODE_2_CLOCK_TICKS;
  1.1802 -			break;
  1.1803 -		case 3:
  1.1804 -			gbTimerClockTicks = gbTimerTicks = GBTIMER_MODE_3_CLOCK_TICKS;
  1.1805 -			break;
  1.1806 -		}
  1.1807 -		return;
  1.1808 -	}
  1.1809 -
  1.1810 -	case 0x0f:
  1.1811 -	{
  1.1812 -		register_IF = value;
  1.1813 -		gbInterrupt = value;
  1.1814 -		return;
  1.1815 -	}
  1.1816 -
  1.1817 -	case 0x10:
  1.1818 -	case 0x11:
  1.1819 -	case 0x12:
  1.1820 -	case 0x13:
  1.1821 -	case 0x14:
  1.1822 -	case 0x15:
  1.1823 -	case 0x16:
  1.1824 -	case 0x17:
  1.1825 -	case 0x18:
  1.1826 -	case 0x19:
  1.1827 -	case 0x1a:
  1.1828 -	case 0x1b:
  1.1829 -	case 0x1c:
  1.1830 -	case 0x1d:
  1.1831 -	case 0x1e:
  1.1832 -	case 0x1f:
  1.1833 -	case 0x20:
  1.1834 -	case 0x21:
  1.1835 -	case 0x22:
  1.1836 -	case 0x23:
  1.1837 -	case 0x24:
  1.1838 -	case 0x25:
  1.1839 -	case 0x26:
  1.1840 -	{
  1.1841 -		SOUND_EVENT(address, value);
  1.1842 -		return;
  1.1843 -	}
  1.1844 -	case 0x40:
  1.1845 -	{
  1.1846 -		int lcdChange = (register_LCDC & 0x80) ^ (value & 0x80);
  1.1847 -
  1.1848 -		if (lcdChange)
  1.1849 -		{
  1.1850 -			if (value & 0x80)
  1.1851 -			{
  1.1852 -				gbLcdTicks	   = GBLCD_MODE_1_CLOCK_TICKS;
  1.1853 -				gbLcdMode	   = 0;
  1.1854 -				register_STAT &= 0xfc;
  1.1855 -				register_LY	   = 0x00;
  1.1856 -				// FIXME: horrible workaround
  1.1857 -				if (gbNullInputHackTempEnabled && !useOldFrameTiming)
  1.1858 -					memcpy(gbJoymask, s_gbJoymask, sizeof(gbJoymask));
  1.1859 -			}
  1.1860 -			else
  1.1861 -			{
  1.1862 -				gbLcdTicks	   = 0;
  1.1863 -				gbLcdMode	   = 0;
  1.1864 -				register_STAT &= 0xfc;
  1.1865 -				register_LY	   = 0x00;
  1.1866 -				// FIXME: horrible workaround
  1.1867 -				memcpy(s_gbJoymask, gbJoymask, sizeof(gbJoymask));
  1.1868 -				if (gbNullInputHackTempEnabled && !useOldFrameTiming)
  1.1869 -					memset(gbJoymask, 0, sizeof(gbJoymask));
  1.1870 -			}
  1.1871 -			//      compareLYToLYC();
  1.1872 -		}
  1.1873 -		// don't draw the window if it was not enabled and not being drawn before
  1.1874 -		if (!(register_LCDC & 0x20) && (value & 0x20) && gbWindowLine == -1 &&
  1.1875 -		    register_LY > register_WY)
  1.1876 -			gbWindowLine = 144;
  1.1877 -
  1.1878 -		register_LCDC = value;
  1.1879 -
  1.1880 -		return;
  1.1881 -	}
  1.1882 -
  1.1883 -	// STAT
  1.1884 -	case 0x41:
  1.1885 -	{
  1.1886 -		//register_STAT = (register_STAT & 0x87) |
  1.1887 -		//      (value & 0x7c);
  1.1888 -		register_STAT = (value & 0xf8) | (register_STAT & 0x07);     // fix ?
  1.1889 -		// GB bug from Devrs FAQ
  1.1890 -		if (!gbCgbMode && (register_LCDC & 0x80) && gbLcdMode < 2)
  1.1891 -			gbInterrupt |= 2;
  1.1892 -		return;
  1.1893 -	}
  1.1894 -
  1.1895 -	// SCY
  1.1896 -	case 0x42:
  1.1897 -	{
  1.1898 -		register_SCY = value;
  1.1899 -		return;
  1.1900 -	}
  1.1901 -
  1.1902 -	// SCX
  1.1903 -	case 0x43:
  1.1904 -	{
  1.1905 -		register_SCX = value;
  1.1906 -		return;
  1.1907 -	}
  1.1908 -
  1.1909 -	// LY
  1.1910 -	case 0x44:
  1.1911 -	{
  1.1912 -		// read only
  1.1913 -		return;
  1.1914 -	}
  1.1915 -
  1.1916 -	// LYC
  1.1917 -	case 0x45:
  1.1918 -	{
  1.1919 -		register_LYC = value;
  1.1920 -		if ((register_LCDC & 0x80))
  1.1921 -		{
  1.1922 -			gbCompareLYToLYC();
  1.1923 -		}
  1.1924 -		return;
  1.1925 -	}
  1.1926 -
  1.1927 -	// DMA!
  1.1928 -	case 0x46:
  1.1929 -	{
  1.1930 -		int source = value * 0x0100;
  1.1931 -
  1.1932 -		gbCopyMemory(0xfe00,
  1.1933 -		             source,
  1.1934 -		             0xa0);
  1.1935 -		register_DMA = value;
  1.1936 -		return;
  1.1937 -	}
  1.1938 -
  1.1939 -	// BGP
  1.1940 -	case 0x47:
  1.1941 -	{
  1.1942 -		gbBgp[0] = value & 0x03;
  1.1943 -		gbBgp[1] = (value & 0x0c) >> 2;
  1.1944 -		gbBgp[2] = (value & 0x30) >> 4;
  1.1945 -		gbBgp[3] = (value & 0xc0) >> 6;
  1.1946 -		break;
  1.1947 -	}
  1.1948 -
  1.1949 -	// OBP0
  1.1950 -	case 0x48:
  1.1951 -	{
  1.1952 -		gbObp0[0] = value & 0x03;
  1.1953 -		gbObp0[1] = (value & 0x0c) >> 2;
  1.1954 -		gbObp0[2] = (value & 0x30) >> 4;
  1.1955 -		gbObp0[3] = (value & 0xc0) >> 6;
  1.1956 -		break;
  1.1957 -	}
  1.1958 -
  1.1959 -	// OBP1
  1.1960 -	case 0x49:
  1.1961 -	{
  1.1962 -		gbObp1[0] = value & 0x03;
  1.1963 -		gbObp1[1] = (value & 0x0c) >> 2;
  1.1964 -		gbObp1[2] = (value & 0x30) >> 4;
  1.1965 -		gbObp1[3] = (value & 0xc0) >> 6;
  1.1966 -		break;
  1.1967 -	}
  1.1968 -
  1.1969 -	case 0x4a:
  1.1970 -		register_WY = value;
  1.1971 -		return;
  1.1972 -
  1.1973 -	case 0x4b:
  1.1974 -		register_WX = value;
  1.1975 -		return;
  1.1976 -
  1.1977 -	// KEY1
  1.1978 -	case 0x4d:
  1.1979 -	{
  1.1980 -		if (gbCgbMode)
  1.1981 -		{
  1.1982 -			gbMemory[0xff4d] = (gbMemory[0xff4d] & 0x80) | (value & 1);
  1.1983 -			return;
  1.1984 -		}
  1.1985 -		break;
  1.1986 -	}
  1.1987 -
  1.1988 -	// VBK
  1.1989 -	case 0x4f:
  1.1990 -	{
  1.1991 -		if (gbCgbMode)
  1.1992 -		{
  1.1993 -			value = value & 1;
  1.1994 -			if (value == gbVramBank)
  1.1995 -				return;
  1.1996 -
  1.1997 -			int vramAddress = value * 0x2000;
  1.1998 -			gbMemoryMap[0x08] = &gbVram[vramAddress];
  1.1999 -			gbMemoryMap[0x09] = &gbVram[vramAddress + 0x1000];
  1.2000 -
  1.2001 -			gbVramBank	 = value;
  1.2002 -			register_VBK = value;
  1.2003 -		}
  1.2004 -		return;
  1.2005 -		break;
  1.2006 -	}
  1.2007 -
  1.2008 -	// HDMA1
  1.2009 -	case 0x51:
  1.2010 -	{
  1.2011 -		if (gbCgbMode)
  1.2012 -		{
  1.2013 -			if (value > 0x7f && value < 0xa0)
  1.2014 -				value = 0;
  1.2015 -
  1.2016 -			gbHdmaSource = (value << 8) | (register_HDMA2 & 0xf0);
  1.2017 -
  1.2018 -			register_HDMA1 = value;
  1.2019 -			return;
  1.2020 -		}
  1.2021 -		break;
  1.2022 -	}
  1.2023 -
  1.2024 -	// HDMA2
  1.2025 -	case 0x52:
  1.2026 -	{
  1.2027 -		if (gbCgbMode)
  1.2028 -		{
  1.2029 -			value = value & 0xf0;
  1.2030 -
  1.2031 -			gbHdmaSource = (register_HDMA1 << 8) | (value);
  1.2032 -
  1.2033 -			register_HDMA2 = value;
  1.2034 -			return;
  1.2035 -		}
  1.2036 -		break;
  1.2037 -	}
  1.2038 -
  1.2039 -	// HDMA3
  1.2040 -	case 0x53:
  1.2041 -	{
  1.2042 -		if (gbCgbMode)
  1.2043 -		{
  1.2044 -			value = value & 0x1f;
  1.2045 -			gbHdmaDestination  = (value << 8) | (register_HDMA4 & 0xf0);
  1.2046 -			gbHdmaDestination += 0x8000;
  1.2047 -			register_HDMA3	   = value;
  1.2048 -			return;
  1.2049 -		}
  1.2050 -		break;
  1.2051 -	}
  1.2052 -
  1.2053 -	// HDMA4
  1.2054 -	case 0x54:
  1.2055 -	{
  1.2056 -		if (gbCgbMode)
  1.2057 -		{
  1.2058 -			value = value & 0xf0;
  1.2059 -			gbHdmaDestination  = ((register_HDMA3 & 0x1f) << 8) | value;
  1.2060 -			gbHdmaDestination += 0x8000;
  1.2061 -			register_HDMA4	   = value;
  1.2062 -			return;
  1.2063 -		}
  1.2064 -		break;
  1.2065 -	}
  1.2066 -
  1.2067 -	// HDMA5
  1.2068 -	case 0x55:
  1.2069 -	{
  1.2070 -		if (gbCgbMode)
  1.2071 -		{
  1.2072 -			gbHdmaBytes = 16 + (value & 0x7f) * 16;
  1.2073 -			if (gbHdmaOn)
  1.2074 -			{
  1.2075 -				if (value & 0x80)
  1.2076 -				{
  1.2077 -					register_HDMA5 = (value & 0x7f);
  1.2078 -				}
  1.2079 -				else
  1.2080 -				{
  1.2081 -					register_HDMA5 = 0xff;
  1.2082 -					gbHdmaOn	   = 0;
  1.2083 -				}
  1.2084 -			}
  1.2085 -			else
  1.2086 -			{
  1.2087 -				if (value & 0x80)
  1.2088 -				{
  1.2089 -					gbHdmaOn	   = 1;
  1.2090 -					register_HDMA5 = value & 0x7f;
  1.2091 -					if (gbLcdMode == 0)
  1.2092 -						gbDoHdma();
  1.2093 -				}
  1.2094 -				else
  1.2095 -				{
  1.2096 -					// we need to take the time it takes to complete the transfer into
  1.2097 -					// account... according to GB DEV FAQs, the setup time is the same
  1.2098 -					// for single and double speed, but the actual transfer takes the
  1.2099 -					// same time // (is that a typo?)
  1.2100 -					switch (gbDMASpeedVersion)
  1.2101 -					{
  1.2102 -					case 1:     // I believe this is more correct
  1.2103 -						// the lower 7 bits of FF55 specify the Transfer Length (divided by 16, minus 1)
  1.2104 -						// and we make gbDmaTicks twice as many cycles at double speed to make the transfer take the same time
  1.2105 -						if (gbSpeed)
  1.2106 -							gbDmaTicks = 16 * ((value & 0x7f) + 1);
  1.2107 -						else
  1.2108 -							gbDmaTicks = 8 * ((value & 0x7f) + 1);
  1.2109 -						break;
  1.2110 -					case 0:     // here for backward compatibility
  1.2111 -						// I think this was a guess that approximates the above in most but not all games
  1.2112 -						if (gbSpeed)
  1.2113 -							gbDmaTicks = 231 + 16 * (value & 0x7f);
  1.2114 -						else
  1.2115 -							gbDmaTicks = 231 + 8 * (value & 0x7f);
  1.2116 -						break;
  1.2117 -					default:     // shouldn't happen
  1.2118 -						//assert(0);
  1.2119 -						break;
  1.2120 -					}
  1.2121 -					gbCopyMemory(gbHdmaDestination, gbHdmaSource, gbHdmaBytes);
  1.2122 -					gbHdmaDestination += gbHdmaBytes;
  1.2123 -					gbHdmaSource	  += gbHdmaBytes;
  1.2124 -
  1.2125 -					register_HDMA3 = ((gbHdmaDestination - 0x8000) >> 8) & 0x1f;
  1.2126 -					register_HDMA4 = gbHdmaDestination & 0xf0;
  1.2127 -					register_HDMA1 = (gbHdmaSource >> 8) & 0xff;
  1.2128 -					register_HDMA2 = gbHdmaSource & 0xf0;
  1.2129 -				}
  1.2130 -			}
  1.2131 -			return;
  1.2132 -		}
  1.2133 -		break;
  1.2134 -	}
  1.2135 -
  1.2136 -	// BCPS
  1.2137 -	case 0x68:
  1.2138 -	{
  1.2139 -		if (gbCgbMode)
  1.2140 -		{
  1.2141 -			int paletteIndex = (value & 0x3f) >> 1;
  1.2142 -			int paletteHiLo	 = (value & 0x01);
  1.2143 -
  1.2144 -			gbMemory[0xff68] = value;
  1.2145 -			gbMemory[0xff69] = (paletteHiLo ?
  1.2146 -			                    (gbPalette[paletteIndex] >> 8) :
  1.2147 -			                    (gbPalette[paletteIndex] & 0x00ff));
  1.2148 -			return;
  1.2149 -		}
  1.2150 -		break;
  1.2151 -	}
  1.2152 -
  1.2153 -	// BCPD
  1.2154 -	case 0x69:
  1.2155 -	{
  1.2156 -		if (gbCgbMode)
  1.2157 -		{
  1.2158 -			int v = gbMemory[0xff68];
  1.2159 -			int paletteIndex = (v & 0x3f) >> 1;
  1.2160 -			int paletteHiLo	 = (v & 0x01);
  1.2161 -			gbMemory[0xff69]		= value;
  1.2162 -			gbPalette[paletteIndex] = (paletteHiLo ?
  1.2163 -			                           ((value << 8) | (gbPalette[paletteIndex] & 0xff)) :
  1.2164 -			                           ((gbPalette[paletteIndex] & 0xff00) | (value))) & 0x7fff;
  1.2165 -
  1.2166 -			if (gbMemory[0xff68] & 0x80)
  1.2167 -			{
  1.2168 -				int index = ((gbMemory[0xff68] & 0x3f) + 1) & 0x3f;
  1.2169 -
  1.2170 -				gbMemory[0xff68] = (gbMemory[0xff68] & 0x80) | index;
  1.2171 -
  1.2172 -				gbMemory[0xff69] = (index & 1 ?
  1.2173 -				                    (gbPalette[index >> 1] >> 8) :
  1.2174 -				                    (gbPalette[index >> 1] & 0x00ff));
  1.2175 -			}
  1.2176 -			return;
  1.2177 -		}
  1.2178 -		break;
  1.2179 -	}
  1.2180 -
  1.2181 -	// OCPS
  1.2182 -	case 0x6a:
  1.2183 -	{
  1.2184 -		if (gbCgbMode)
  1.2185 -		{
  1.2186 -			int paletteIndex = (value & 0x3f) >> 1;
  1.2187 -			int paletteHiLo	 = (value & 0x01);
  1.2188 -
  1.2189 -			paletteIndex += 32;
  1.2190 -
  1.2191 -			gbMemory[0xff6a] = value;
  1.2192 -			gbMemory[0xff6b] = (paletteHiLo ?
  1.2193 -			                    (gbPalette[paletteIndex] >> 8) :
  1.2194 -			                    (gbPalette[paletteIndex] & 0x00ff));
  1.2195 -			return;
  1.2196 -		}
  1.2197 -		break;
  1.2198 -	}
  1.2199 -
  1.2200 -	// OCPD
  1.2201 -	case 0x6b:
  1.2202 -	{
  1.2203 -		if (gbCgbMode)
  1.2204 -		{
  1.2205 -			int v = gbMemory[0xff6a];
  1.2206 -			int paletteIndex = (v & 0x3f) >> 1;
  1.2207 -			int paletteHiLo	 = (v & 0x01);
  1.2208 -
  1.2209 -			paletteIndex += 32;
  1.2210 -
  1.2211 -			gbMemory[0xff6b]		= value;
  1.2212 -			gbPalette[paletteIndex] = (paletteHiLo ?
  1.2213 -			                           ((value << 8) | (gbPalette[paletteIndex] & 0xff)) :
  1.2214 -			                           ((gbPalette[paletteIndex] & 0xff00) | (value))) & 0x7fff;
  1.2215 -			if (gbMemory[0xff6a] & 0x80)
  1.2216 -			{
  1.2217 -				int index = ((gbMemory[0xff6a] & 0x3f) + 1) & 0x3f;
  1.2218 -
  1.2219 -				gbMemory[0xff6a] = (gbMemory[0xff6a] & 0x80) | index;
  1.2220 -
  1.2221 -				gbMemory[0xff6b] = (index & 1 ?
  1.2222 -				                    (gbPalette[(index >> 1) + 32] >> 8) :
  1.2223 -				                    (gbPalette[(index >> 1) + 32] & 0x00ff));
  1.2224 -			}
  1.2225 -			return;
  1.2226 -		}
  1.2227 -		break;
  1.2228 -	}
  1.2229 -
  1.2230 -	// SVBK
  1.2231 -	case 0x70:
  1.2232 -	{
  1.2233 -		if (gbCgbMode)
  1.2234 -		{
  1.2235 -			value = value & 7;
  1.2236 -
  1.2237 -			int bank = value;
  1.2238 -			if (value == 0)
  1.2239 -				bank = 1;
  1.2240 -
  1.2241 -			if (bank == gbWramBank)
  1.2242 -				return;
  1.2243 -
  1.2244 -			int wramAddress = bank * 0x1000;
  1.2245 -			gbMemoryMap[0x0d] = &gbWram[wramAddress];
  1.2246 -
  1.2247 -			gbWramBank	  = bank;
  1.2248 -			register_SVBK = value;
  1.2249 -			return;
  1.2250 -		}
  1.2251 -		break;
  1.2252 -	}
  1.2253 -
  1.2254 -	case 0xff:
  1.2255 -	{
  1.2256 -		register_IE	 = value;
  1.2257 -		register_IF &= value;
  1.2258 -		return;
  1.2259 -	}
  1.2260 -	}
  1.2261 -
  1.2262 -	gbWriteMemoryQuick(address, value);
  1.2263 -}
  1.2264 -
  1.2265 -u8 gbReadOpcode(register u16 address)
  1.2266 -{
  1.2267 -	if (gbCheatMap[address])
  1.2268 -		return gbCheatRead(address);
  1.2269 -
  1.2270 -	// the following fix does more than Echo RAM fix, anyway...
  1.2271 -	switch (gbEchoRAMFixOn ? (address >> 12) & 0x000f : address & 0xf000)
  1.2272 -	{
  1.2273 -	case 0x0a:
  1.2274 -	case 0x0b:
  1.2275 -		if (mapperReadRAM)
  1.2276 -			return mapperReadRAM(address);
  1.2277 -		break;
  1.2278 -	case 0x0f:
  1.2279 -		if (address > 0xff00)
  1.2280 -		{
  1.2281 -			switch (address & 0x00ff)
  1.2282 -			{
  1.2283 -			case 0x04:
  1.2284 -				return register_DIV;
  1.2285 -			case 0x05:
  1.2286 -				return register_TIMA;
  1.2287 -			case 0x06:
  1.2288 -				return register_TMA;
  1.2289 -			case 0x07:
  1.2290 -				return (0xf8 | register_TAC);
  1.2291 -			case 0x0f:
  1.2292 -				return (0xe0 | register_IF);
  1.2293 -			case 0x40:
  1.2294 -				return register_LCDC;
  1.2295 -			case 0x41:
  1.2296 -				return (0x80 | register_STAT);
  1.2297 -			case 0x42:
  1.2298 -				return register_SCY;
  1.2299 -			case 0x43:
  1.2300 -				return register_SCX;
  1.2301 -			case 0x44:
  1.2302 -				return register_LY;
  1.2303 -			case 0x45:
  1.2304 -				return register_LYC;
  1.2305 -			case 0x46:
  1.2306 -				return register_DMA;
  1.2307 -			case 0x4a:
  1.2308 -				return register_WY;
  1.2309 -			case 0x4b:
  1.2310 -				return register_WX;
  1.2311 -			case 0x4f:
  1.2312 -				return (0xfe | register_VBK);
  1.2313 -			case 0x51:
  1.2314 -				return register_HDMA1;
  1.2315 -			case 0x52:
  1.2316 -				return register_HDMA2;
  1.2317 -			case 0x53:
  1.2318 -				return register_HDMA3;
  1.2319 -			case 0x54:
  1.2320 -				return register_HDMA4;
  1.2321 -			case 0x55:
  1.2322 -				return register_HDMA5;
  1.2323 -			case 0x70:
  1.2324 -				return (0xf8 | register_SVBK);
  1.2325 -			case 0xff:
  1.2326 -				return register_IE;
  1.2327 -			}
  1.2328 -		}
  1.2329 -		break;
  1.2330 -	}
  1.2331 -	return gbReadMemoryQuick(address);
  1.2332 -}
  1.2333 -
  1.2334 -void gbWriteMemory(register u16 address, register u8 value)
  1.2335 -{
  1.2336 -	gbWriteMemoryWrapped(address, value);
  1.2337 -	CallRegisteredLuaMemHook(address, 1, value, LUAMEMHOOK_WRITE);
  1.2338 -}
  1.2339 -
  1.2340 -u8 gbReadMemory(register u16 address)
  1.2341 -{
  1.2342 -	if (gbCheatMap[address])
  1.2343 -		return gbCheatRead(address);
  1.2344 -
  1.2345 -	if (address < 0xa000)
  1.2346 -		return gbReadMemoryQuick(address);
  1.2347 -
  1.2348 -	if (address < 0xc000)
  1.2349 -	{
  1.2350 -#ifndef FINAL_VERSION
  1.2351 -		if (memorydebug)
  1.2352 -		{
  1.2353 -			log("Memory register read %04x PC=%04x\n",
  1.2354 -			    address,
  1.2355 -			    PC.W);
  1.2356 -		}
  1.2357 -#endif
  1.2358 -
  1.2359 -		if (mapperReadRAM)
  1.2360 -			return mapperReadRAM(address);
  1.2361 -		return gbReadMemoryQuick(address);
  1.2362 -	}
  1.2363 -
  1.2364 -	if (address >= 0xff00)
  1.2365 -	{
  1.2366 -		switch (address & 0x00ff)
  1.2367 -		{
  1.2368 -		case 0x00:
  1.2369 -		{
  1.2370 -			if (gbSgbMode)
  1.2371 -			{
  1.2372 -				gbSgbReadingController |= 4;
  1.2373 -				gbSgbResetPacketState();
  1.2374 -			}
  1.2375 -
  1.2376 -			int b = gbMemory[0xff00];
  1.2377 -
  1.2378 -			if ((b & 0x30) == 0x20)
  1.2379 -			{
  1.2380 -				b &= 0xf0;
  1.2381 -
  1.2382 -				int joy = 0;
  1.2383 -				if (gbSgbMode && gbSgbMultiplayer)
  1.2384 -				{
  1.2385 -					switch (gbSgbNextController)
  1.2386 -					{
  1.2387 -					case 0x0f:
  1.2388 -						joy = 0;
  1.2389 -						break;
  1.2390 -					case 0x0e:
  1.2391 -						joy = 1;
  1.2392 -						break;
  1.2393 -					case 0x0d:
  1.2394 -						joy = 2;
  1.2395 -						break;
  1.2396 -					case 0x0c:
  1.2397 -						joy = 3;
  1.2398 -						break;
  1.2399 -					default:
  1.2400 -						joy = 0;
  1.2401 -					}
  1.2402 -				}
  1.2403 -				int joystate = gbJoymask[joy];
  1.2404 -				if (!(joystate & 128))
  1.2405 -					b |= 0x08;
  1.2406 -				if (!(joystate & 64))
  1.2407 -					b |= 0x04;
  1.2408 -				if (!(joystate & 32))
  1.2409 -					b |= 0x02;
  1.2410 -				if (!(joystate & 16))
  1.2411 -					b |= 0x01;
  1.2412 -
  1.2413 -				gbMemory[0xff00] = b;
  1.2414 -			}
  1.2415 -			else if ((b & 0x30) == 0x10)
  1.2416 -			{
  1.2417 -				b &= 0xf0;
  1.2418 -
  1.2419 -				int joy = 0;
  1.2420 -				if (gbSgbMode && gbSgbMultiplayer)
  1.2421 -				{
  1.2422 -					switch (gbSgbNextController)
  1.2423 -					{
  1.2424 -					case 0x0f:
  1.2425 -						joy = 0;
  1.2426 -						break;
  1.2427 -					case 0x0e:
  1.2428 -						joy = 1;
  1.2429 -						break;
  1.2430 -					case 0x0d:
  1.2431 -						joy = 2;
  1.2432 -						break;
  1.2433 -					case 0x0c:
  1.2434 -						joy = 3;
  1.2435 -						break;
  1.2436 -					default:
  1.2437 -						joy = 0;
  1.2438 -					}
  1.2439 -				}
  1.2440 -				int joystate = gbJoymask[joy];
  1.2441 -				if (!(joystate & 8))
  1.2442 -					b |= 0x08;
  1.2443 -				if (!(joystate & 4))
  1.2444 -					b |= 0x04;
  1.2445 -				if (!(joystate & 2))
  1.2446 -					b |= 0x02;
  1.2447 -				if (!(joystate & 1))
  1.2448 -					b |= 0x01;
  1.2449 -
  1.2450 -				gbMemory[0xff00] = b;
  1.2451 -			}
  1.2452 -			else
  1.2453 -			{
  1.2454 -				if (gbSgbMode && gbSgbMultiplayer)
  1.2455 -				{
  1.2456 -					gbMemory[0xff00] = 0xf0 | gbSgbNextController;
  1.2457 -				}
  1.2458 -				else
  1.2459 -				{
  1.2460 -					gbMemory[0xff00] = 0xff;
  1.2461 -				}
  1.2462 -			}
  1.2463 -		}
  1.2464 -			GBSystemCounters.lagged = false;
  1.2465 -			return gbMemory[0xff00];
  1.2466 -			break;
  1.2467 -		case 0x01:
  1.2468 -			return gbMemory[0xff01];
  1.2469 -		case 0x04:
  1.2470 -			return register_DIV;
  1.2471 -		case 0x05:
  1.2472 -			return register_TIMA;
  1.2473 -		case 0x06:
  1.2474 -			return register_TMA;
  1.2475 -		case 0x07:
  1.2476 -			return (0xf8 | register_TAC);
  1.2477 -		case 0x0f:
  1.2478 -			return (0xe0 | register_IF);
  1.2479 -		case 0x40:
  1.2480 -			return register_LCDC;
  1.2481 -		case 0x41:
  1.2482 -			return (0x80 | register_STAT);
  1.2483 -		case 0x42:
  1.2484 -			return register_SCY;
  1.2485 -		case 0x43:
  1.2486 -			return register_SCX;
  1.2487 -		case 0x44:
  1.2488 -			return register_LY;
  1.2489 -		case 0x45:
  1.2490 -			return register_LYC;
  1.2491 -		case 0x46:
  1.2492 -			return register_DMA;
  1.2493 -		case 0x4a:
  1.2494 -			return register_WY;
  1.2495 -		case 0x4b:
  1.2496 -			return register_WX;
  1.2497 -		case 0x4f:
  1.2498 -			return (0xfe | register_VBK);
  1.2499 -		case 0x51:
  1.2500 -			return register_HDMA1;
  1.2501 -		case 0x52:
  1.2502 -			return register_HDMA2;
  1.2503 -		case 0x53:
  1.2504 -			return register_HDMA3;
  1.2505 -		case 0x54:
  1.2506 -			return register_HDMA4;
  1.2507 -		case 0x55:
  1.2508 -			return register_HDMA5;
  1.2509 -		case 0x70:
  1.2510 -			return (0xf8 | register_SVBK);
  1.2511 -		case 0xff:
  1.2512 -			return register_IE;
  1.2513 -		}
  1.2514 -	}
  1.2515 -
  1.2516 -	return gbReadMemoryQuick(address);
  1.2517 +    }
  1.2518 +
  1.2519 +  return gbReadMemoryQuick(address);
  1.2520  }
  1.2521  
  1.2522  void gbVblank_interrupt()
  1.2523  {
  1.2524 -	if (IFF & 0x80)
  1.2525 -	{
  1.2526 -		PC.W++;
  1.2527 -		IFF &= 0x7f;
  1.2528 -	}
  1.2529 -	gbInterrupt &= 0xfe;
  1.2530 -
  1.2531 -	IFF			&= 0x7e;
  1.2532 -	register_IF &= 0xfe;
  1.2533 -
  1.2534 -	gbWriteMemory(--SP.W, PC.B.B1);
  1.2535 -	gbWriteMemory(--SP.W, PC.B.B0);
  1.2536 -	PC.W = 0x40;
  1.2537 +  if (IFF & 0x80)
  1.2538 +    {
  1.2539 +      PC.W++;
  1.2540 +      IFF &= 0x7f;
  1.2541 +    }
  1.2542 +  gbInterrupt &= 0xfe;
  1.2543 +
  1.2544 +  IFF			&= 0x7e;
  1.2545 +  register_IF &= 0xfe;
  1.2546 +
  1.2547 +  gbWriteMemory(--SP.W, PC.B.B1);
  1.2548 +  gbWriteMemory(--SP.W, PC.B.B0);
  1.2549 +  PC.W = 0x40;
  1.2550  }
  1.2551  
  1.2552  void gbLcd_interrupt()
  1.2553  {
  1.2554 -	if (IFF & 0x80)
  1.2555 -	{
  1.2556 -		PC.W++;
  1.2557 -		IFF &= 0x7f;
  1.2558 -	}
  1.2559 -	gbInterrupt &= 0xfd;
  1.2560 -	IFF			&= 0x7e;
  1.2561 -	register_IF &= 0xfd;
  1.2562 -
  1.2563 -	gbWriteMemory(--SP.W, PC.B.B1);
  1.2564 -	gbWriteMemory(--SP.W, PC.B.B0);
  1.2565 -
  1.2566 -	PC.W = 0x48;
  1.2567 +  if (IFF & 0x80)
  1.2568 +    {
  1.2569 +      PC.W++;
  1.2570 +      IFF &= 0x7f;
  1.2571 +    }
  1.2572 +  gbInterrupt &= 0xfd;
  1.2573 +  IFF			&= 0x7e;
  1.2574 +  register_IF &= 0xfd;
  1.2575 +
  1.2576 +  gbWriteMemory(--SP.W, PC.B.B1);
  1.2577 +  gbWriteMemory(--SP.W, PC.B.B0);
  1.2578 +
  1.2579 +  PC.W = 0x48;
  1.2580  }
  1.2581  
  1.2582  void gbTimer_interrupt()
  1.2583  {
  1.2584 -	if (IFF & 0x80)
  1.2585 -	{
  1.2586 -		PC.W++;
  1.2587 -		IFF &= 0x7f;
  1.2588 -	}
  1.2589 -	IFF			&= 0x7e;
  1.2590 -	gbInterrupt &= 0xfb;
  1.2591 -	register_IF &= 0xfb;
  1.2592 -
  1.2593 -	gbWriteMemory(--SP.W, PC.B.B1);
  1.2594 -	gbWriteMemory(--SP.W, PC.B.B0);
  1.2595 -
  1.2596 -	PC.W = 0x50;
  1.2597 +  if (IFF & 0x80)
  1.2598 +    {
  1.2599 +      PC.W++;
  1.2600 +      IFF &= 0x7f;
  1.2601 +    }
  1.2602 +  IFF			&= 0x7e;
  1.2603 +  gbInterrupt &= 0xfb;
  1.2604 +  register_IF &= 0xfb;
  1.2605 +
  1.2606 +  gbWriteMemory(--SP.W, PC.B.B1);
  1.2607 +  gbWriteMemory(--SP.W, PC.B.B0);
  1.2608 +
  1.2609 +  PC.W = 0x50;
  1.2610  }
  1.2611  
  1.2612  void gbSerial_interrupt()
  1.2613  {
  1.2614 -	if (IFF & 0x80)
  1.2615 -	{
  1.2616 -		PC.W++;
  1.2617 -		IFF &= 0x7f;
  1.2618 -	}
  1.2619 -	IFF			&= 0x7e;
  1.2620 -	gbInterrupt &= 0xf7;
  1.2621 -	register_IF &= 0xf7;
  1.2622 -
  1.2623 -	gbWriteMemory(--SP.W, PC.B.B1);
  1.2624 -	gbWriteMemory(--SP.W, PC.B.B0);
  1.2625 -
  1.2626 -	PC.W = 0x58;
  1.2627 +  if (IFF & 0x80)
  1.2628 +    {
  1.2629 +      PC.W++;
  1.2630 +      IFF &= 0x7f;
  1.2631 +    }
  1.2632 +  IFF			&= 0x7e;
  1.2633 +  gbInterrupt &= 0xf7;
  1.2634 +  register_IF &= 0xf7;
  1.2635 +
  1.2636 +  gbWriteMemory(--SP.W, PC.B.B1);
  1.2637 +  gbWriteMemory(--SP.W, PC.B.B0);
  1.2638 +
  1.2639 +  PC.W = 0x58;
  1.2640  }
  1.2641  
  1.2642  void gbJoypad_interrupt()
  1.2643  {
  1.2644 -	if (IFF & 0x80)
  1.2645 -	{
  1.2646 -		PC.W++;
  1.2647 -		IFF &= 0x7f;
  1.2648 -	}
  1.2649 -	IFF			&= 0x7e;
  1.2650 -	gbInterrupt &= 0xef;
  1.2651 -	register_IF &= 0xef;
  1.2652 -
  1.2653 -	gbWriteMemory(--SP.W, PC.B.B1);
  1.2654 -	gbWriteMemory(--SP.W, PC.B.B0);
  1.2655 -
  1.2656 -	PC.W = 0x60;
  1.2657 +  if (IFF & 0x80)
  1.2658 +    {
  1.2659 +      PC.W++;
  1.2660 +      IFF &= 0x7f;
  1.2661 +    }
  1.2662 +  IFF			&= 0x7e;
  1.2663 +  gbInterrupt &= 0xef;
  1.2664 +  register_IF &= 0xef;
  1.2665 +
  1.2666 +  gbWriteMemory(--SP.W, PC.B.B1);
  1.2667 +  gbWriteMemory(--SP.W, PC.B.B0);
  1.2668 +
  1.2669 +  PC.W = 0x60;
  1.2670  }
  1.2671  
  1.2672  void gbSpeedSwitch()
  1.2673  {
  1.2674 -	if (gbSpeed == 0)
  1.2675 -	{
  1.2676 -		gbSpeed = 1;
  1.2677 -		GBLCD_MODE_0_CLOCK_TICKS   = 51 * 2; //127; //51 * 2;
  1.2678 -		GBLCD_MODE_1_CLOCK_TICKS   = 1140 * 2;
  1.2679 -		GBLCD_MODE_2_CLOCK_TICKS   = 20 * 2; //52; //20 * 2;
  1.2680 -		GBLCD_MODE_3_CLOCK_TICKS   = 43 * 2; //99; //43 * 2;
  1.2681 -		GBDIV_CLOCK_TICKS		   = 64 * 2;
  1.2682 -		GBLY_INCREMENT_CLOCK_TICKS = 114 * 2;
  1.2683 -		GBTIMER_MODE_0_CLOCK_TICKS = 256; //256*2;
  1.2684 -		GBTIMER_MODE_1_CLOCK_TICKS = 4; //4*2;
  1.2685 -		GBTIMER_MODE_2_CLOCK_TICKS = 16; //16*2;
  1.2686 -		GBTIMER_MODE_3_CLOCK_TICKS = 64; //64*2;
  1.2687 -		GBSERIAL_CLOCK_TICKS	   = 128 * 2;
  1.2688 -		gbDivTicks *= 2;
  1.2689 -		gbLcdTicks *= 2;
  1.2690 -		gbLcdLYIncrementTicks *= 2;
  1.2691 -		//    timerTicks *= 2;
  1.2692 -		//    timerClockTicks *= 2;
  1.2693 -		gbSerialTicks	 *= 2;
  1.2694 -		SOUND_CLOCK_TICKS = soundQuality * GB_USE_TICKS_AS * 2;
  1.2695 -		soundTicks		 *= 2;
  1.2696 -		//    synchronizeTicks *= 2;
  1.2697 -		//    SYNCHRONIZE_CLOCK_TICKS *= 2;
  1.2698 -	}
  1.2699 -	else
  1.2700 -	{
  1.2701 -		gbSpeed = 0;
  1.2702 -		GBLCD_MODE_0_CLOCK_TICKS   = 51;
  1.2703 -		GBLCD_MODE_1_CLOCK_TICKS   = 1140;
  1.2704 -		GBLCD_MODE_2_CLOCK_TICKS   = 20;
  1.2705 -		GBLCD_MODE_3_CLOCK_TICKS   = 43;
  1.2706 -		GBDIV_CLOCK_TICKS		   = 64;
  1.2707 -		GBLY_INCREMENT_CLOCK_TICKS = 114;
  1.2708 -		GBTIMER_MODE_0_CLOCK_TICKS = 256;
  1.2709 -		GBTIMER_MODE_1_CLOCK_TICKS = 4;
  1.2710 -		GBTIMER_MODE_2_CLOCK_TICKS = 16;
  1.2711 -		GBTIMER_MODE_3_CLOCK_TICKS = 64;
  1.2712 -		GBSERIAL_CLOCK_TICKS	   = 128;
  1.2713 -		gbDivTicks /= 2;
  1.2714 -		gbLcdTicks /= 2;
  1.2715 -		gbLcdLYIncrementTicks /= 2;
  1.2716 -		//    timerTicks /= 2;
  1.2717 -		//    timerClockTicks /= 2;
  1.2718 -		gbSerialTicks	 /= 2;
  1.2719 -		SOUND_CLOCK_TICKS = soundQuality * GB_USE_TICKS_AS;
  1.2720 -		soundTicks		 /= 2;
  1.2721 -		//    synchronizeTicks /= 2;
  1.2722 -		//    SYNCHRONIZE_CLOCK_TICKS /= 2;
  1.2723 -	}
  1.2724 +  if (gbSpeed == 0)
  1.2725 +    {
  1.2726 +      gbSpeed = 1;
  1.2727 +      GBLCD_MODE_0_CLOCK_TICKS   = 51 * 2; //127; //51 * 2;
  1.2728 +      GBLCD_MODE_1_CLOCK_TICKS   = 1140 * 2;
  1.2729 +      GBLCD_MODE_2_CLOCK_TICKS   = 20 * 2; //52; //20 * 2;
  1.2730 +      GBLCD_MODE_3_CLOCK_TICKS   = 43 * 2; //99; //43 * 2;
  1.2731 +      GBDIV_CLOCK_TICKS		   = 64 * 2;
  1.2732 +      GBLY_INCREMENT_CLOCK_TICKS = 114 * 2;
  1.2733 +      GBTIMER_MODE_0_CLOCK_TICKS = 256; //256*2;
  1.2734 +      GBTIMER_MODE_1_CLOCK_TICKS = 4; //4*2;
  1.2735 +      GBTIMER_MODE_2_CLOCK_TICKS = 16; //16*2;
  1.2736 +      GBTIMER_MODE_3_CLOCK_TICKS = 64; //64*2;
  1.2737 +      GBSERIAL_CLOCK_TICKS	   = 128 * 2;
  1.2738 +      gbDivTicks *= 2;
  1.2739 +      gbLcdTicks *= 2;
  1.2740 +      gbLcdLYIncrementTicks *= 2;
  1.2741 +      //    timerTicks *= 2;
  1.2742 +      //    timerClockTicks *= 2;
  1.2743 +      gbSerialTicks	 *= 2;
  1.2744 +      SOUND_CLOCK_TICKS = soundQuality * GB_USE_TICKS_AS * 2;
  1.2745 +      soundTicks		 *= 2;
  1.2746 +      //    synchronizeTicks *= 2;
  1.2747 +      //    SYNCHRONIZE_CLOCK_TICKS *= 2;
  1.2748 +    }
  1.2749 +  else
  1.2750 +    {
  1.2751 +      gbSpeed = 0;
  1.2752 +      GBLCD_MODE_0_CLOCK_TICKS   = 51;
  1.2753 +      GBLCD_MODE_1_CLOCK_TICKS   = 1140;
  1.2754 +      GBLCD_MODE_2_CLOCK_TICKS   = 20;
  1.2755 +      GBLCD_MODE_3_CLOCK_TICKS   = 43;
  1.2756 +      GBDIV_CLOCK_TICKS		   = 64;
  1.2757 +      GBLY_INCREMENT_CLOCK_TICKS = 114;
  1.2758 +      GBTIMER_MODE_0_CLOCK_TICKS = 256;
  1.2759 +      GBTIMER_MODE_1_CLOCK_TICKS = 4;
  1.2760 +      GBTIMER_MODE_2_CLOCK_TICKS = 16;
  1.2761 +      GBTIMER_MODE_3_CLOCK_TICKS = 64;
  1.2762 +      GBSERIAL_CLOCK_TICKS	   = 128;
  1.2763 +      gbDivTicks /= 2;
  1.2764 +      gbLcdTicks /= 2;
  1.2765 +      gbLcdLYIncrementTicks /= 2;
  1.2766 +      //    timerTicks /= 2;
  1.2767 +      //    timerClockTicks /= 2;
  1.2768 +      gbSerialTicks	 /= 2;
  1.2769 +      SOUND_CLOCK_TICKS = soundQuality * GB_USE_TICKS_AS;
  1.2770 +      soundTicks		 /= 2;
  1.2771 +      //    synchronizeTicks /= 2;
  1.2772 +      //    SYNCHRONIZE_CLOCK_TICKS /= 2;
  1.2773 +    }
  1.2774  }
  1.2775  
  1.2776  void gbGetHardwareType()
  1.2777  {
  1.2778 -	gbCgbMode = 0;
  1.2779 -	if (gbRom[0x143] & 0x80)
  1.2780 +  gbCgbMode = 0;
  1.2781 +  if (gbRom[0x143] & 0x80)
  1.2782 +    {
  1.2783 +      if (gbEmulatorType == 0 ||
  1.2784 +	  gbEmulatorType == 1 ||
  1.2785 +	  gbEmulatorType == 4 ||
  1.2786 +	  gbEmulatorType == 5 ||
  1.2787 +	  (gbRom[0x146] != 0x03 && (gbEmulatorType == 2)))
  1.2788  	{
  1.2789 -		if (gbEmulatorType == 0 ||
  1.2790 -		    gbEmulatorType == 1 ||
  1.2791 -		    gbEmulatorType == 4 ||
  1.2792 -		    gbEmulatorType == 5 ||
  1.2793 -		    (gbRom[0x146] != 0x03 && (gbEmulatorType == 2)))
  1.2794 -		{
  1.2795 -			gbCgbMode = 1;
  1.2796 -		}
  1.2797 +	  gbCgbMode = 1;
  1.2798  	}
  1.2799 -
  1.2800 -	if (gbSgbMode == 2)
  1.2801 -	{
  1.2802 -		gbSgbMode = 0;
  1.2803 -		return;
  1.2804 -	}
  1.2805 -
  1.2806 -	gbSgbMode = 0;
  1.2807 -	if (gbRom[0x146] == 0x03)
  1.2808 -	{
  1.2809 -		if (gbEmulatorType == 0 ||
  1.2810 -		    gbEmulatorType == 2 ||
  1.2811 -		    gbEmulatorType == 5 ||
  1.2812 -		    (!(gbRom[0x143] & 0x80) && (gbEmulatorType == 1 || gbEmulatorType == 4)))
  1.2813 -			gbSgbMode = 1;
  1.2814 -	}
  1.2815 +    }
  1.2816 +
  1.2817 +  if (gbSgbMode == 2)
  1.2818 +    {
  1.2819 +      gbSgbMode = 0;
  1.2820 +      return;
  1.2821 +    }
  1.2822 +
  1.2823 +  gbSgbMode = 0;
  1.2824 +  if (gbRom[0x146] == 0x03)
  1.2825 +    {
  1.2826 +      if (gbEmulatorType == 0 ||
  1.2827 +	  gbEmulatorType == 2 ||
  1.2828 +	  gbEmulatorType == 5 ||
  1.2829 +	  (!(gbRom[0x143] & 0x80) && (gbEmulatorType == 1 || gbEmulatorType == 4)))
  1.2830 +	gbSgbMode = 1;
  1.2831 +    }
  1.2832  }
  1.2833  
  1.2834  void gbReset(bool userReset)
  1.2835  {
  1.2836 -	// movie must be closed while opening/creating a movie
  1.2837 -	if (userReset && VBAMovieRecording())
  1.2838 +  // movie must be closed while opening/creating a movie
  1.2839 +  if (userReset && VBAMovieRecording())
  1.2840 +    {
  1.2841 +      VBAMovieSignalReset();
  1.2842 +      return;
  1.2843 +    }
  1.2844 +
  1.2845 +  if (!VBAMovieActive())
  1.2846 +    {
  1.2847 +      GBSystemCounters.frameCount = 0;
  1.2848 +      GBSystemCounters.lagCount	= 0;
  1.2849 +      GBSystemCounters.extraCount = 0;
  1.2850 +      GBSystemCounters.lagged		= true;
  1.2851 +      GBSystemCounters.laggedLast = true;
  1.2852 +    }
  1.2853 +
  1.2854 +  SP.W = 0xfffe;
  1.2855 +  AF.W = 0x01b0;
  1.2856 +  BC.W = 0x0013;
  1.2857 +  DE.W = 0x00d8;
  1.2858 +  HL.W = 0x014d;
  1.2859 +  PC.W = 0x0100;
  1.2860 +  IFF	 = 0;
  1.2861 +  gbInterrupt		= 1;
  1.2862 +  gbInterruptWait = 0;
  1.2863 +
  1.2864 +  register_DIV   = 0;
  1.2865 +  register_TIMA  = 0;
  1.2866 +  register_TMA   = 0;
  1.2867 +  register_TAC   = 0;
  1.2868 +  register_IF	   = 1;
  1.2869 +  register_LCDC  = 0x91;
  1.2870 +  register_STAT  = 0;
  1.2871 +  register_SCY   = 0;
  1.2872 +  register_SCX   = 0;
  1.2873 +  register_LY	   = 0;
  1.2874 +  register_LYC   = 0;
  1.2875 +  register_DMA   = 0;
  1.2876 +  register_WY	   = 0;
  1.2877 +  register_WX	   = 0;
  1.2878 +  register_VBK   = 0;
  1.2879 +  register_HDMA1 = 0;
  1.2880 +  register_HDMA2 = 0;
  1.2881 +  register_HDMA3 = 0;
  1.2882 +  register_HDMA4 = 0;
  1.2883 +  register_HDMA5 = 0;
  1.2884 +  register_SVBK  = 0;
  1.2885 +  register_IE	   = 0;
  1.2886 +
  1.2887 +  gbGetHardwareType();
  1.2888 +  if (gbCgbMode)
  1.2889 +    {
  1.2890 +      if (!gbVram)
  1.2891 +	gbVram = (u8 *)malloc(0x4000 + 4);
  1.2892 +      if (!gbWram)
  1.2893 +	gbWram = (u8 *)malloc(0x8000 + 4);
  1.2894 +      memset(gbVram, 0, 0x4000 + 4);
  1.2895 +      memset(gbWram, 0, 0x8000 + 4);
  1.2896 +    }
  1.2897 +  else
  1.2898 +    {
  1.2899 +      if (gbVram)
  1.2900  	{
  1.2901 -		VBAMovieSignalReset();
  1.2902 -		return;
  1.2903 +	  free(gbVram);
  1.2904 +	  gbVram = NULL;
  1.2905  	}
  1.2906 -
  1.2907 -	if (!VBAMovieActive())
  1.2908 +      if (gbWram)
  1.2909  	{
  1.2910 -		GBSystemCounters.frameCount = 0;
  1.2911 -		GBSystemCounters.lagCount	= 0;
  1.2912 -		GBSystemCounters.extraCount = 0;
  1.2913 -		GBSystemCounters.lagged		= true;
  1.2914 -		GBSystemCounters.laggedLast = true;
  1.2915 +	  free(gbWram);
  1.2916 +	  gbWram = NULL;
  1.2917  	}
  1.2918 -
  1.2919 -	SP.W = 0xfffe;
  1.2920 -	AF.W = 0x01b0;
  1.2921 -	BC.W = 0x0013;
  1.2922 -	DE.W = 0x00d8;
  1.2923 -	HL.W = 0x014d;
  1.2924 -	PC.W = 0x0100;
  1.2925 -	IFF	 = 0;
  1.2926 -	gbInterrupt		= 1;
  1.2927 -	gbInterruptWait = 0;
  1.2928 -
  1.2929 -	register_DIV   = 0;
  1.2930 -	register_TIMA  = 0;
  1.2931 -	register_TMA   = 0;
  1.2932 -	register_TAC   = 0;
  1.2933 -	register_IF	   = 1;
  1.2934 -	register_LCDC  = 0x91;
  1.2935 -	register_STAT  = 0;
  1.2936 -	register_SCY   = 0;
  1.2937 -	register_SCX   = 0;
  1.2938 -	register_LY	   = 0;
  1.2939 -	register_LYC   = 0;
  1.2940 -	register_DMA   = 0;
  1.2941 -	register_WY	   = 0;
  1.2942 -	register_WX	   = 0;
  1.2943 -	register_VBK   = 0;
  1.2944 -	register_HDMA1 = 0;
  1.2945 -	register_HDMA2 = 0;
  1.2946 -	register_HDMA3 = 0;
  1.2947 -	register_HDMA4 = 0;
  1.2948 -	register_HDMA5 = 0;
  1.2949 -	register_SVBK  = 0;
  1.2950 -	register_IE	   = 0;
  1.2951 -
  1.2952 -	gbGetHardwareType();
  1.2953 -	if (gbCgbMode)
  1.2954 +    }
  1.2955 +
  1.2956 +  // clean LineBuffer
  1.2957 +  if (gbLineBuffer)
  1.2958 +    memset(gbLineBuffer, 0, 160 * sizeof(u16));
  1.2959 +  // clean Pix
  1.2960 +  if (pix)
  1.2961 +    memset(pix, 0, 4 * 257 * 226);
  1.2962 +
  1.2963 +  if (gbCgbMode)
  1.2964 +    {
  1.2965 +      if (gbSgbMode)
  1.2966  	{
  1.2967 -		if (!gbVram)
  1.2968 -			gbVram = (u8 *)malloc(0x4000 + 4);
  1.2969 -		if (!gbWram)
  1.2970 -			gbWram = (u8 *)malloc(0x8000 + 4);
  1.2971 -		memset(gbVram, 0, 0x4000 + 4);
  1.2972 -		memset(gbWram, 0, 0x8000 + 4);
  1.2973 +	  if (gbEmulatorType == 5)
  1.2974 +	    AF.W = 0xffb0;
  1.2975 +	  else
  1.2976 +	    AF.W = 0x01b0;
  1.2977 +	  BC.W = 0x0013;
  1.2978 +	  DE.W = 0x00d8;
  1.2979 +	  HL.W = 0x014d;
  1.2980  	}
  1.2981 -	else
  1.2982 +      else
  1.2983  	{
  1.2984 -		if (gbVram)
  1.2985 -		{
  1.2986 -			free(gbVram);
  1.2987 -			gbVram = NULL;
  1.2988 -		}
  1.2989 -		if (gbWram)
  1.2990 -		{
  1.2991 -			free(gbWram);
  1.2992 -			gbWram = NULL;
  1.2993 -		}
  1.2994 +	  AF.W = 0x11b0;
  1.2995 +	  BC.W = 0x0000;
  1.2996 +	  DE.W = 0xff56;
  1.2997 +	  HL.W = 0x000d;
  1.2998  	}
  1.2999 -
  1.3000 -	// clean LineBuffer
  1.3001 -	if (gbLineBuffer)
  1.3002 -		memset(gbLineBuffer, 0, 160 * sizeof(u16));
  1.3003 -	// clean Pix
  1.3004 -	if (pix)
  1.3005 -		memset(pix, 0, 4 * 257 * 226);
  1.3006 -
  1.3007 -	if (gbCgbMode)
  1.3008 -	{
  1.3009 -		if (gbSgbMode)
  1.3010 -		{
  1.3011 -			if (gbEmulatorType == 5)
  1.3012 -				AF.W = 0xffb0;
  1.3013 -			else
  1.3014 -				AF.W = 0x01b0;
  1.3015 -			BC.W = 0x0013;
  1.3016 -			DE.W = 0x00d8;
  1.3017 -			HL.W = 0x014d;
  1.3018 -		}
  1.3019 -		else
  1.3020 -		{
  1.3021 -			AF.W = 0x11b0;
  1.3022 -			BC.W = 0x0000;
  1.3023 -			DE.W = 0xff56;
  1.3024 -			HL.W = 0x000d;
  1.3025 -		}
  1.3026 -		if (gbEmulatorType == 4)
  1.3027 -			BC.B.B1 |= 0x01;
  1.3028 -
  1.3029 -		register_HDMA5	 = 0xff;
  1.3030 -		gbMemory[0xff68] = 0xc0;
  1.3031 -		gbMemory[0xff6a] = 0xc0;
  1.3032 -
  1.3033 -		for (int i = 0; i < 64; i++)
  1.3034 -			gbPalette[i] = 0x7fff;
  1.3035 -	}
  1.3036 -	else
  1.3037 -	{
  1.3038 -		for (int i = 0; i < 8; i++)
  1.3039 -			gbPalette[i] = systemGbPalette[gbPaletteOption * 8 + i];
  1.3040 -	}
  1.3041 -
  1.3042 -	if (gbSpeed)
  1.3043 -	{
  1.3044 -		gbSpeedSwitch();
  1.3045 -		gbMemory[0xff4d] = 0;
  1.3046 -	}
  1.3047 -
  1.3048 -	gbDivTicks = GBDIV_CLOCK_TICKS;
  1.3049 -	gbLcdMode  = 2;
  1.3050 -	gbLcdTicks = GBLCD_MODE_2_CLOCK_TICKS;
  1.3051 -	gbLcdLYIncrementTicks = 0;
  1.3052 -	gbTimerTicks		  = 0;
  1.3053 -	gbTimerClockTicks	  = 0;
  1.3054 -	gbSerialTicks		  = 0;
  1.3055 -	gbSerialBits		  = 0;
  1.3056 -	gbSerialOn			  = 0;
  1.3057 -	gbWindowLine		  = -1;
  1.3058 -	gbTimerOn			  = 0;
  1.3059 -	gbTimerMode			  = 0;
  1.3060 -	//  gbSynchronizeTicks = GBSYNCHRONIZE_CLOCK_TICKS;
  1.3061 -	gbSpeed		 = 0;
  1.3062 -	gbJoymask[0] = gbJoymask[1] = gbJoymask[2] = gbJoymask[3] = 0;
  1.3063 -
  1.3064 -	// FIXME: horrible kludge
  1.3065 -	memset(s_gbJoymask, 0, sizeof(s_gbJoymask));
  1.3066 -
  1.3067 -	if (gbCgbMode)
  1.3068 -	{
  1.3069 -		gbSpeed	 = 0;
  1.3070 -		gbHdmaOn = 0;
  1.3071 -		gbHdmaSource	  = 0x0000;
  1.3072 -		gbHdmaDestination = 0x8000;
  1.3073 -		gbVramBank		  = 0;
  1.3074 -		gbWramBank		  = 1;
  1.3075 -		register_LY		  = 0x90;
  1.3076 -		gbLcdMode		  = 1;
  1.3077 -	}
  1.3078 -
  1.3079 -	if (gbSgbMode)
  1.3080 -	{
  1.3081 -		gbSgbReset();
  1.3082 -	}
  1.3083 -
  1.3084 -	for (int i = 0; i < 4; i++)
  1.3085 -		gbBgp[i] = gbObp0[i] = gbObp1[i] = i;
  1.3086 -
  1.3087 -	memset(&gbDataMBC1, 0, sizeof(gbDataMBC1));
  1.3088 -	gbDataMBC1.mapperROMBank = 1;
  1.3089 -
  1.3090 -	gbDataMBC2.mapperRAMEnable = 0;
  1.3091 -	gbDataMBC2.mapperROMBank   = 1;
  1.3092 -
  1.3093 -	memset(&gbDataMBC3, 0, 6 * sizeof(int32));
  1.3094 -	gbDataMBC3.mapperROMBank = 1;
  1.3095 -
  1.3096 -	memset(&gbDataMBC5, 0, sizeof(gbDataMBC5));
  1.3097 -	gbDataMBC5.mapperROMBank = 1;
  1.3098 -	switch (gbRom[0x147])
  1.3099 -	{
  1.3100 -	case 0x1c:
  1.3101 -	case 0x1d:
  1.3102 -	case 0x1e:
  1.3103 -		gbDataMBC5.isRumbleCartridge = 1;
  1.3104 -	}
  1.3105 -
  1.3106 -	memset(&gbDataHuC1, 0, sizeof(gbDataHuC1));
  1.3107 -	gbDataHuC1.mapperROMBank = 1;
  1.3108 -
  1.3109 -	memset(&gbDataHuC3, 0, sizeof(gbDataHuC3));
  1.3110 -	gbDataHuC3.mapperROMBank = 1;
  1.3111 -
  1.3112 -	gbMemoryMap[0x00] = &gbRom[0x0000];
  1.3113 -	gbMemoryMap[0x01] = &gbRom[0x1000];
  1.3114 -	gbMemoryMap[0x02] = &gbRom[0x2000];
  1.3115 -	gbMemoryMap[0x03] = &gbRom[0x3000];
  1.3116 -	gbMemoryMap[0x04] = &gbRom[0x4000];
  1.3117 -	gbMemoryMap[0x05] = &gbRom[0x5000];
  1.3118 -	gbMemoryMap[0x06] = &gbRom[0x6000];
  1.3119 -	gbMemoryMap[0x07] = &gbRom[0x7000];
  1.3120 -	if (gbCgbMode)
  1.3121 -	{
  1.3122 -		gbMemoryMap[0x08] = &gbVram[0x0000];
  1.3123 -		gbMemoryMap[0x09] = &gbVram[0x1000];
  1.3124 -		gbMemoryMap[0x0a] = &gbMemory[0xa000];
  1.3125 -		gbMemoryMap[0x0b] = &gbMemory[0xb000];
  1.3126 -		gbMemoryMap[0x0c] = &gbMemory[0xc000];
  1.3127 -		gbMemoryMap[0x0d] = &gbWram[0x1000];
  1.3128 -		gbMemoryMap[0x0e] = &gbMemory[0xe000];
  1.3129 -		gbMemoryMap[0x0f] = &gbMemory[0xf000];
  1.3130 -	}
  1.3131 -	else
  1.3132 -	{
  1.3133 -		gbMemoryMap[0x08] = &gbMemory[0x8000];
  1.3134 -		gbMemoryMap[0x09] = &gbMemory[0x9000];
  1.3135 -		gbMemoryMap[0x0a] = &gbMemory[0xa000];
  1.3136 -		gbMemoryMap[0x0b] = &gbMemory[0xb000];
  1.3137 -		gbMemoryMap[0x0c] = &gbMemory[0xc000];
  1.3138 -		gbMemoryMap[0x0d] = &gbMemory[0xd000];
  1.3139 -		gbMemoryMap[0x0e] = &gbMemory[0xe000];
  1.3140 -		gbMemoryMap[0x0f] = &gbMemory[0xf000];
  1.3141 -	}
  1.3142 -
  1.3143 -	if (gbRam)
  1.3144 -	{
  1.3145 -		gbMemoryMap[0x0a] = &gbRam[0x0000];
  1.3146 -		gbMemoryMap[0x0b] = &gbRam[0x1000];
  1.3147 -	}
  1.3148 -
  1.3149 -	gbSoundReset();
  1.3150 -
  1.3151 -	systemResetSensor();
  1.3152 -
  1.3153 -	systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED;
  1.3154 -
  1.3155 -	gbLastTime	 = systemGetClock();
  1.3156 -	gbFrameCount = 0;
  1.3157 -
  1.3158 -	systemRefreshScreen();
  1.3159 +      if (gbEmulatorType == 4)
  1.3160 +	BC.B.B1 |= 0x01;
  1.3161 +
  1.3162 +      register_HDMA5	 = 0xff;
  1.3163 +      gbMemory[0xff68] = 0xc0;
  1.3164 +      gbMemory[0xff6a] = 0xc0;
  1.3165 +
  1.3166 +      for (int i = 0; i < 64; i++)
  1.3167 +	gbPalette[i] = 0x7fff;
  1.3168 +    }
  1.3169 +  else
  1.3170 +    {
  1.3171 +      for (int i = 0; i < 8; i++)
  1.3172 +	gbPalette[i] = systemGbPalette[gbPaletteOption * 8 + i];
  1.3173 +    }
  1.3174 +
  1.3175 +  if (gbSpeed)
  1.3176 +    {
  1.3177 +      gbSpeedSwitch();
  1.3178 +      gbMemory[0xff4d] = 0;
  1.3179 +    }
  1.3180 +
  1.3181 +  gbDivTicks = GBDIV_CLOCK_TICKS;
  1.3182 +  gbLcdMode  = 2;
  1.3183 +  gbLcdTicks = GBLCD_MODE_2_CLOCK_TICKS;
  1.3184 +  gbLcdLYIncrementTicks = 0;
  1.3185 +  gbTimerTicks		  = 0;
  1.3186 +  gbTimerClockTicks	  = 0;
  1.3187 +  gbSerialTicks		  = 0;
  1.3188 +  gbSerialBits		  = 0;
  1.3189 +  gbSerialOn			  = 0;
  1.3190 +  gbWindowLine		  = -1;
  1.3191 +  gbTimerOn			  = 0;
  1.3192 +  gbTimerMode			  = 0;
  1.3193 +  //  gbSynchronizeTicks = GBSYNCHRONIZE_CLOCK_TICKS;
  1.3194 +  gbSpeed		 = 0;
  1.3195 +  gbJoymask[0] = gbJoymask[1] = gbJoymask[2] = gbJoymask[3] = 0;
  1.3196 +
  1.3197 +  // FIXME: horrible kludge
  1.3198 +  memset(s_gbJoymask, 0, sizeof(s_gbJoymask));
  1.3199 +
  1.3200 +  if (gbCgbMode)
  1.3201 +    {
  1.3202 +      gbSpeed	 = 0;
  1.3203 +      gbHdmaOn = 0;
  1.3204 +      gbHdmaSource	  = 0x0000;
  1.3205 +      gbHdmaDestination = 0x8000;
  1.3206 +      gbVramBank		  = 0;
  1.3207 +      gbWramBank		  = 1;
  1.3208 +      register_LY		  = 0x90;
  1.3209 +      gbLcdMode		  = 1;
  1.3210 +    }
  1.3211 +
  1.3212 +  if (gbSgbMode)
  1.3213 +    {
  1.3214 +      gbSgbReset();
  1.3215 +    }
  1.3216 +
  1.3217 +  for (int i = 0; i < 4; i++)
  1.3218 +    gbBgp[i] = gbObp0[i] = gbObp1[i] = i;
  1.3219 +
  1.3220 +  memset(&gbDataMBC1, 0, sizeof(gbDataMBC1));
  1.3221 +  gbDataMBC1.mapperROMBank = 1;
  1.3222 +
  1.3223 +  gbDataMBC2.mapperRAMEnable = 0;
  1.3224 +  gbDataMBC2.mapperROMBank   = 1;
  1.3225 +
  1.3226 +  memset(&gbDataMBC3, 0, 6 * sizeof(int32));
  1.3227 +  gbDataMBC3.mapperROMBank = 1;
  1.3228 +
  1.3229 +  memset(&gbDataMBC5, 0, sizeof(gbDataMBC5));
  1.3230 +  gbDataMBC5.mapperROMBank = 1;
  1.3231 +  switch (gbRom[0x147])
  1.3232 +    {
  1.3233 +    case 0x1c:
  1.3234 +    case 0x1d:
  1.3235 +    case 0x1e:
  1.3236 +      gbDataMBC5.isRumbleCartridge = 1;
  1.3237 +    }
  1.3238 +
  1.3239 +  memset(&gbDataHuC1, 0, sizeof(gbDataHuC1));
  1.3240 +  gbDataHuC1.mapperROMBank = 1;
  1.3241 +
  1.3242 +  memset(&gbDataHuC3, 0, sizeof(gbDataHuC3));
  1.3243 +  gbDataHuC3.mapperROMBank = 1;
  1.3244 +
  1.3245 +  gbMemoryMap[0x00] = &gbRom[0x0000];
  1.3246 +  gbMemoryMap[0x01] = &gbRom[0x1000];
  1.3247 +  gbMemoryMap[0x02] = &gbRom[0x2000];
  1.3248 +  gbMemoryMap[0x03] = &gbRom[0x3000];
  1.3249 +  gbMemoryMap[0x04] = &gbRom[0x4000];
  1.3250 +  gbMemoryMap[0x05] = &gbRom[0x5000];
  1.3251 +  gbMemoryMap[0x06] = &gbRom[0x6000];
  1.3252 +  gbMemoryMap[0x07] = &gbRom[0x7000];
  1.3253 +  if (gbCgbMode)
  1.3254 +    {
  1.3255 +      gbMemoryMap[0x08] = &gbVram[0x0000];
  1.3256 +      gbMemoryMap[0x09] = &gbVram[0x1000];
  1.3257 +      gbMemoryMap[0x0a] = &gbMemory[0xa000];
  1.3258 +      gbMemoryMap[0x0b] = &gbMemory[0xb000];
  1.3259 +      gbMemoryMap[0x0c] = &gbMemory[0xc000];
  1.3260 +      gbMemoryMap[0x0d] = &gbWram[0x1000];
  1.3261 +      gbMemoryMap[0x0e] = &gbMemory[0xe000];
  1.3262 +      gbMemoryMap[0x0f] = &gbMemory[0xf000];
  1.3263 +    }
  1.3264 +  else
  1.3265 +    {
  1.3266 +      gbMemoryMap[0x08] = &gbMemory[0x8000];
  1.3267 +      gbMemoryMap[0x09] = &gbMemory[0x9000];
  1.3268 +      gbMemoryMap[0x0a] = &gbMemory[0xa000];
  1.3269 +      gbMemoryMap[0x0b] = &gbMemory[0xb000];
  1.3270 +      gbMemoryMap[0x0c] = &gbMemory[0xc000];
  1.3271 +      gbMemoryMap[0x0d] = &gbMemory[0xd000];
  1.3272 +      gbMemoryMap[0x0e] = &gbMemory[0xe000];
  1.3273 +      gbMemoryMap[0x0f] = &gbMemory[0xf000];
  1.3274 +    }
  1.3275 +
  1.3276 +  if (gbRam)
  1.3277 +    {
  1.3278 +      gbMemoryMap[0x0a] = &gbRam[0x0000];
  1.3279 +      gbMemoryMap[0x0b] = &gbRam[0x1000];
  1.3280 +    }
  1.3281 +
  1.3282 +  gbSoundReset();
  1.3283 +
  1.3284 +  systemResetSensor();
  1.3285 +
  1.3286 +  systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED;
  1.3287 +
  1.3288 +  gbLastTime	 = systemGetClock();
  1.3289 +  gbFrameCount = 0;
  1.3290 +
  1.3291 +  systemRefreshScreen();
  1.3292  }
  1.3293  
  1.3294  void gbWriteSaveMBC1(const char *name)
  1.3295  {
  1.3296 -	FILE *gzFile = fopen(name, "wb");
  1.3297 -
  1.3298 -	if (gzFile == NULL)
  1.3299 -	{
  1.3300 -		systemMessage(MSG_ERROR_CREATING_FILE, N_("Error creating file %s"), name);
  1.3301 -		return;
  1.3302 -	}
  1.3303 -
  1.3304 -	fwrite(gbRam,
  1.3305 -	       1,
  1.3306 -	       gbRamSize,
  1.3307 -	       gzFile);
  1.3308 -
  1.3309 -	fclose(gzFile);
  1.3310 +  FILE *gzFile = fopen(name, "wb");
  1.3311 +
  1.3312 +  if (gzFile == NULL)
  1.3313 +    {
  1.3314 +      systemMessage(MSG_ERROR_CREATING_FILE, N_("Error creating file %s"), name);
  1.3315 +      return;
  1.3316 +    }
  1.3317 +
  1.3318 +  fwrite(gbRam,
  1.3319 +	 1,
  1.3320 +	 gbRamSize,
  1.3321 +	 gzFile);
  1.3322 +
  1.3323 +  fclose(gzFile);
  1.3324  }
  1.3325  
  1.3326  void gbWriteSaveMBC2(const char *name)
  1.3327  {
  1.3328 -	FILE *file = fopen(name, "wb");
  1.3329 -
  1.3330 -	if (file == NULL)
  1.3331 -	{
  1.3332 -		systemMessage(MSG_ERROR_CREATING_FILE, N_("Error creating file %s"), name);
  1.3333 -		return;
  1.3334 -	}
  1.3335 -
  1.3336 -	fwrite(&gbMemory[0xa000],
  1.3337 -	       1,
  1.3338 -	       256,
  1.3339 -	       file);
  1.3340 -
  1.3341 -	fclose(file);
  1.3342 +  FILE *file = fopen(name, "wb");
  1.3343 +
  1.3344 +  if (file == NULL)
  1.3345 +    {
  1.3346 +      systemMessage(MSG_ERROR_CREATING_FILE, N_("Error creating file %s"), name);
  1.3347 +      return;
  1.3348 +    }
  1.3349 +
  1.3350 +  fwrite(&gbMemory[0xa000],
  1.3351 +	 1,
  1.3352 +	 256,
  1.3353 +	 file);
  1.3354 +
  1.3355 +  fclose(file);
  1.3356  }
  1.3357  
  1.3358  void gbWriteSaveMBC3(const char *name, bool extendedSave)
  1.3359  {
  1.3360 -	FILE *gzFile = fopen(name, "wb");
  1.3361 -
  1.3362 -	if (gzFile == NULL)
  1.3363 -	{
  1.3364 -		systemMessage(MSG_ERROR_CREATING_FILE, N_("Error creating file %s"), name);
  1.3365 -		return;
  1.3366 -	}
  1.3367 -
  1.3368 -	fwrite(gbRam,
  1.3369 -	       1,
  1.3370 -	       gbRamSize,
  1.3371 -	       gzFile);
  1.3372 -
  1.3373 -	if (extendedSave)
  1.3374 -	{
  1.3375 -		//assert(sizeof(time_t) == 4);
  1.3376 -		fwrite(&gbDataMBC3.mapperSeconds,
  1.3377 -		       1,
  1.3378 -		       10 * sizeof(int32) + /*sizeof(time_t)*/4,
  1.3379 -		       gzFile);
  1.3380 -	}
  1.3381 -
  1.3382 -	fclose(gzFile);
  1.3383 +  FILE *gzFile = fopen(name, "wb");
  1.3384 +
  1.3385 +  if (gzFile == NULL)
  1.3386 +    {
  1.3387 +      systemMessage(MSG_ERROR_CREATING_FILE, N_("Error creating file %s"), name);
  1.3388 +      return;
  1.3389 +    }
  1.3390 +
  1.3391 +  fwrite(gbRam,
  1.3392 +	 1,
  1.3393 +	 gbRamSize,
  1.3394 +	 gzFile);
  1.3395 +
  1.3396 +  if (extendedSave)
  1.3397 +    {
  1.3398 +      //assert(sizeof(time_t) == 4);
  1.3399 +      fwrite(&gbDataMBC3.mapperSeconds,
  1.3400 +	     1,
  1.3401 +	     10 * sizeof(int32) + /*sizeof(time_t)*/4,
  1.3402 +	     gzFile);
  1.3403 +    }
  1.3404 +
  1.3405 +  fclose(gzFile);
  1.3406  }
  1.3407  
  1.3408  void gbWriteSaveMBC5(const char *name)
  1.3409  {
  1.3410 -	FILE *gzFile = fopen(name, "wb");
  1.3411 -
  1.3412 -	if (gzFile == NULL)
  1.3413 -	{
  1.3414 -		systemMessage(MSG_ERROR_CREATING_FILE, N_("Error creating file %s"), name);
  1.3415 -		return;
  1.3416 -	}
  1.3417 -
  1.3418 -	fwrite(gbRam,
  1.3419 -	       1,
  1.3420 -	       gbRamSize,
  1.3421 -	       gzFile);
  1.3422 -
  1.3423 -	fclose(gzFile);
  1.3424 +  FILE *gzFile = fopen(name, "wb");
  1.3425 +
  1.3426 +  if (gzFile == NULL)
  1.3427 +    {
  1.3428 +      systemMessage(MSG_ERROR_CREATING_FILE, N_("Error creating file %s"), name);
  1.3429 +      return;
  1.3430 +    }
  1.3431 +
  1.3432 +  fwrite(gbRam,
  1.3433 +	 1,
  1.3434 +	 gbRamSize,
  1.3435 +	 gzFile);
  1.3436 +
  1.3437 +  fclose(gzFile);
  1.3438  }
  1.3439  
  1.3440  void gbWriteSaveMBC7(const char *name)
  1.3441  {
  1.3442 -	FILE *file = fopen(name, "wb");
  1.3443 -
  1.3444 -	if (file == NULL)
  1.3445 -	{
  1.3446 -		systemMessage(MSG_ERROR_CREATING_FILE, N_("Error creating file %s"), name);
  1.3447 -		return;
  1.3448 -	}
  1.3449 -
  1.3450 -	fwrite(&gbMemory[0xa000],
  1.3451 -	       1,
  1.3452 -	       256,
  1.3453 -	       file);
  1.3454 -
  1.3455 -	fclose(file);
  1.3456 +  FILE *file = fopen(name, "wb");
  1.3457 +
  1.3458 +  if (file == NULL)
  1.3459 +    {
  1.3460 +      systemMessage(MSG_ERROR_CREATING_FILE, N_("Error creating file %s"), name);
  1.3461 +      return;
  1.3462 +    }
  1.3463 +
  1.3464 +  fwrite(&gbMemory[0xa000],
  1.3465 +	 1,
  1.3466 +	 256,
  1.3467 +	 file);
  1.3468 +
  1.3469 +  fclose(file);
  1.3470  }
  1.3471  
  1.3472  bool gbReadSaveMBC1(const char *name)
  1.3473  {
  1.3474 -	gzFile gzFile = gzopen(name, "rb");
  1.3475 -
  1.3476 -	if (gzFile == NULL)
  1.3477 -	{
  1.3478 -		return false;
  1.3479 -	}
  1.3480 -
  1.3481 -	int read = gzread(gzFile,
  1.3482 -	                  gbRam,
  1.3483 -	                  gbRamSize);
  1.3484 -
  1.3485 -	if (read != gbRamSize)
  1.3486 -	{
  1.3487 -		systemMessage(MSG_FAILED_TO_READ_SGM, N_("Failed to read complete save game %s (%d)"), name, read);
  1.3488 -		gzclose(gzFile);
  1.3489 -		return false;
  1.3490 -	}
  1.3491 -
  1.3492 -	gzclose(gzFile);
  1.3493 -	return true;
  1.3494 +  gzFile gzFile = gzopen(name, "rb");
  1.3495 +
  1.3496 +  if (gzFile == NULL)
  1.3497 +    {
  1.3498 +      return false;
  1.3499 +    }
  1.3500 +
  1.3501 +  int read = gzread(gzFile,
  1.3502 +		    gbRam,
  1.3503 +		    gbRamSize);
  1.3504 +
  1.3505 +  if (read != gbRamSize)
  1.3506 +    {
  1.3507 +      systemMessage(MSG_FAILED_TO_READ_SGM, N_("Failed to read complete save game %s (%d)"), name, read);
  1.3508 +      gzclose(gzFile);
  1.3509 +      return false;
  1.3510 +    }
  1.3511 +
  1.3512 +  gzclose(gzFile);
  1.3513 +  return true;
  1.3514  }
  1.3515  
  1.3516  bool gbReadSaveMBC2(const char *name)
  1.3517  {
  1.3518 -	FILE *file = fopen(name, "rb");
  1.3519 -
  1.3520 -	if (file == NULL)
  1.3521 -	{
  1.3522 -		return false;
  1.3523 -	}
  1.3524 -
  1.3525 -	int read = fread(&gbMemory[0xa000],
  1.3526 -	                 1,
  1.3527 -	                 256,
  1.3528 -	                 file);
  1.3529 -
  1.3530 -	if (read != 256)
  1.3531 -	{
  1.3532 -		systemMessage(MSG_FAILED_TO_READ_SGM,
  1.3533 -		              N_("Failed to read complete save game %s (%d)"), name, read);
  1.3534 -		fclose(file);
  1.3535 -		return false;
  1.3536 -	}
  1.3537 -
  1.3538 -	fclose(file);
  1.3539 -	return true;
  1.3540 +  FILE *file = fopen(name, "rb");
  1.3541 +
  1.3542 +  if (file == NULL)
  1.3543 +    {
  1.3544 +      return false;
  1.3545 +    }
  1.3546 +
  1.3547 +  int read = fread(&gbMemory[0xa000],
  1.3548 +		   1,
  1.3549 +		   256,
  1.3550 +		   file);
  1.3551 +
  1.3552 +  if (read != 256)
  1.3553 +    {
  1.3554 +      systemMessage(MSG_FAILED_TO_READ_SGM,
  1.3555 +		    N_("Failed to read complete save game %s (%d)"), name, read);
  1.3556 +      fclose(file);
  1.3557 +      return false;
  1.3558 +    }
  1.3559 +
  1.3560 +  fclose(file);
  1.3561 +  return true;
  1.3562  }
  1.3563  
  1.3564  bool gbReadSaveMBC3(const char *name)
  1.3565  {
  1.3566 -	gzFile gzFile = gzopen(name, "rb");
  1.3567 -
  1.3568 -	if (gzFile == NULL)
  1.3569 +  gzFile gzFile = gzopen(name, "rb");
  1.3570 +
  1.3571 +  if (gzFile == NULL)
  1.3572 +    {
  1.3573 +      return false;
  1.3574 +    }
  1.3575 +
  1.3576 +  int read = gzread(gzFile,
  1.3577 +		    gbRam,
  1.3578 +		    gbRamSize);
  1.3579 +
  1.3580 +  bool res = true;
  1.3581 +
  1.3582 +  if (read != gbRamSize)
  1.3583 +    {
  1.3584 +      systemMessage(MSG_FAILED_TO_READ_SGM,
  1.3585 +		    N_("Failed to read complete save game %s (%d)"), name, read);
  1.3586 +    }
  1.3587 +  else
  1.3588 +    {
  1.3589 +      //assert(sizeof(time_t) == 4);
  1.3590 +      read = gzread(gzFile,
  1.3591 +		    &gbDataMBC3.mapperSeconds,
  1.3592 +		    sizeof(int32) * 10 + /*sizeof(time_t)*/4);
  1.3593 +
  1.3594 +      if (read != (sizeof(int32) * 10 + /*sizeof(time_t)*/4) && read != 0)
  1.3595  	{
  1.3596 -		return false;
  1.3597 +	  systemMessage(MSG_FAILED_TO_READ_RTC,
  1.3598 +			N_("Failed to read RTC from save game %s (continuing)"),
  1.3599 +			name);
  1.3600 +	  res = false;
  1.3601  	}
  1.3602 -
  1.3603 -	int read = gzread(gzFile,
  1.3604 -	                  gbRam,
  1.3605 -	                  gbRamSize);
  1.3606 -
  1.3607 -	bool res = true;
  1.3608 -
  1.3609 -	if (read != gbRamSize)
  1.3610 -	{
  1.3611 -		systemMessage(MSG_FAILED_TO_READ_SGM,
  1.3612 -		              N_("Failed to read complete save game %s (%d)"), name, read);
  1.3613 -	}
  1.3614 -	else
  1.3615 -	{
  1.3616 -		//assert(sizeof(time_t) == 4);
  1.3617 -		read = gzread(gzFile,
  1.3618 -		              &gbDataMBC3.mapperSeconds,
  1.3619 -		              sizeof(int32) * 10 + /*sizeof(time_t)*/4);
  1.3620 -
  1.3621 -		if (read != (sizeof(int32) * 10 + /*sizeof(time_t)*/4) && read != 0)
  1.3622 -		{
  1.3623 -			systemMessage(MSG_FAILED_TO_READ_RTC,
  1.3624 -			              N_("Failed to read RTC from save game %s (continuing)"),
  1.3625 -			              name);
  1.3626 -			res = false;
  1.3627 -		}
  1.3628 -	}
  1.3629 -
  1.3630 -	gzclose(gzFile);
  1.3631 -	return res;
  1.3632 +    }
  1.3633 +
  1.3634 +  gzclose(gzFile);
  1.3635 +  return res;
  1.3636  }
  1.3637  
  1.3638  bool gbReadSaveMBC5(const char *name)
  1.3639  {
  1.3640 -	gzFile gzFile = gzopen(name, "rb");
  1.3641 -
  1.3642 -	if (gzFile == NULL)
  1.3643 -	{
  1.3644 -		return false;
  1.3645 -	}
  1.3646 -
  1.3647 -	int read = gzread(gzFile,
  1.3648 -	                  gbRam,
  1.3649 -	                  gbRamSize);
  1.3650 -
  1.3651 -	if (read != gbRamSize)
  1.3652 -	{
  1.3653 -		systemMessage(MSG_FAILED_TO_READ_SGM,
  1.3654 -		              N_("Failed to read complete save game %s (%d)"), name, read);
  1.3655 -		gzclose(gzFile);
  1.3656 -		return false;
  1.3657 -	}
  1.3658 -
  1.3659 -	gzclose(gzFile);
  1.3660 -	return true;
  1.3661 +  gzFile gzFile = gzopen(name, "rb");
  1.3662 +
  1.3663 +  if (gzFile == NULL)
  1.3664 +    {
  1.3665 +      return false;
  1.3666 +    }
  1.3667 +
  1.3668 +  int read = gzread(gzFile,
  1.3669 +		    gbRam,
  1.3670 +		    gbRamSize);
  1.3671 +
  1.3672 +  if (read != gbRamSize)
  1.3673 +    {
  1.3674 +      systemMessage(MSG_FAILED_TO_READ_SGM,
  1.3675 +		    N_("Failed to read complete save game %s (%d)"), name, read);
  1.3676 +      gzclose(gzFile);
  1.3677 +      return false;
  1.3678 +    }
  1.3679 +
  1.3680 +  gzclose(gzFile);
  1.3681 +  return true;
  1.3682  }
  1.3683  
  1.3684  bool gbReadSaveMBC7(const char *name)
  1.3685  {
  1.3686 -	FILE *file = fopen(name, "rb");
  1.3687 -
  1.3688 -	if (file == NULL)
  1.3689 -	{
  1.3690 -		return false;
  1.3691 -	}
  1.3692 -
  1.3693 -	int read = fread(&gbMemory[0xa000],
  1.3694 -	                 1,
  1.3695 -	                 256,
  1.3696 -	                 file);
  1.3697 -
  1.3698 -	if (read != 256)
  1.3699 -	{
  1.3700 -		systemMessage(MSG_FAILED_TO_READ_SGM,
  1.3701 -		              N_("Failed to read complete save game %s (%d)"), name, read);
  1.3702 -		fclose(file);
  1.3703 -		return false;
  1.3704 -	}
  1.3705 -
  1.3706 -	fclose(file);
  1.3707 -	return true;
  1.3708 +  FILE *file = fopen(name, "rb");
  1.3709 +
  1.3710 +  if (file == NULL)
  1.3711 +    {
  1.3712 +      return false;
  1.3713 +    }
  1.3714 +
  1.3715 +  int read = fread(&gbMemory[0xa000],
  1.3716 +		   1,
  1.3717 +		   256,
  1.3718 +		   file);
  1.3719 +
  1.3720 +  if (read != 256)
  1.3721 +    {
  1.3722 +      systemMessage(MSG_FAILED_TO_READ_SGM,
  1.3723 +		    N_("Failed to read complete save game %s (%d)"), name, read);
  1.3724 +      fclose(file);
  1.3725 +      return false;
  1.3726 +    }
  1.3727 +
  1.3728 +  fclose(file);
  1.3729 +  return true;
  1.3730  }
  1.3731  
  1.3732  #if 0
  1.3733  bool gbLoadBIOS(const char *biosFileName, bool useBiosFile)
  1.3734  {
  1.3735 -	useBios = false;
  1.3736 -	if (useBiosFile)
  1.3737 +  useBios = false;
  1.3738 +  if (useBiosFile)
  1.3739 +    {
  1.3740 +      useBios = utilLoadBIOS(bios, biosFileName, gbEmulatorType);
  1.3741 +      if (!useBios)
  1.3742  	{
  1.3743 -		useBios = utilLoadBIOS(bios, biosFileName, gbEmulatorType);
  1.3744 -		if (!useBios)
  1.3745 -		{
  1.3746 -			systemMessage(MSG_INVALID_BIOS_FILE_SIZE, N_("Invalid BOOTROM file"));
  1.3747 -		}
  1.3748 +	  systemMessage(MSG_INVALID_BIOS_FILE_SIZE, N_("Invalid BOOTROM file"));
  1.3749  	}
  1.3750 -	return useBios;
  1.3751 +    }
  1.3752 +  return useBios;
  1.3753  }
  1.3754  #endif
  1.3755  
  1.3756  void gbInit()
  1.3757  {
  1.3758 -	gbGenFilter();
  1.3759 -	gbSgbInit();    // calls gbSgbReset()... whatever
  1.3760 -
  1.3761 -	gbMemory = (u8 *)malloc(65536 + 4);
  1.3762 -	memset(gbMemory, 0, 65536 + 4);
  1.3763 -	memset(gbPalette, 0, 2 * 128);
  1.3764 -
  1.3765 -	// HACK: +4 at start to accomodate the 2xSaI filter reading out of bounds of the leftmost pixel
  1.3766 -	origPix = (u8 *)calloc(1, 4 * 257 * 226 + 4);
  1.3767 -	pix		= origPix + 4;
  1.3768 -
  1.3769 -	gbLineBuffer = (u16 *)malloc(160 * sizeof(u16));
  1.3770 +  gbGenFilter();
  1.3771 +  gbSgbInit();    // calls gbSgbReset()... whatever
  1.3772 +
  1.3773 +  gbMemory = (u8 *)malloc(65536 + 4);
  1.3774 +  memset(gbMemory, 0, 65536 + 4);
  1.3775 +  memset(gbPalette, 0, 2 * 128);
  1.3776 +
  1.3777 +  // HACK: +4 at start to accomodate the 2xSaI filter reading out of bounds of the leftmost pixel
  1.3778 +  origPix = (u8 *)calloc(1, 4 * 257 * 226 + 4);
  1.3779 +  pix		= origPix + 4;
  1.3780 +
  1.3781 +  gbLineBuffer = (u16 *)malloc(160 * sizeof(u16));
  1.3782  }
  1.3783  
  1.3784  bool gbWriteBatteryFile(const char *file, bool extendedSave)
  1.3785  {
  1.3786 -	if (gbBattery)
  1.3787 -	{
  1.3788 -		int type = gbRom[0x147];
  1.3789 -
  1.3790 -		switch (type)
  1.3791 -		{
  1.3792 -		case 0x03:
  1.3793 -			gbWriteSaveMBC1(file);
  1.3794 -			break;
  1.3795 -		case 0x06:
  1.3796 -			gbWriteSaveMBC2(file);
  1.3797 -			break;
  1.3798 -		case 0x0f:
  1.3799 -		case 0x10:
  1.3800 -		case 0x13:
  1.3801 -			gbWriteSaveMBC3(file, extendedSave);
  1.3802 -			break;
  1.3803 -		case 0x1b:
  1.3804 -		case 0x1e:
  1.3805 -			gbWriteSaveMBC5(file);
  1.3806 -			break;
  1.3807 -		case 0x22:
  1.3808 -			gbWriteSaveMBC7(file);
  1.3809 -			break;
  1.3810 -		case 0xff:
  1.3811 -			gbWriteSaveMBC1(file);
  1.3812 -			break;
  1.3813 -		}
  1.3814 -	}
  1.3815 -	return true;
  1.3816 -}
  1.3817 -
  1.3818 -bool gbWriteBatteryFile(const char *file)
  1.3819 -{
  1.3820 -	gbWriteBatteryFile(file, true);
  1.3821 -	return true;
  1.3822 -}
  1.3823 -
  1.3824 -bool gbWriteBatteryToStream(gzFile gzfile)
  1.3825 -{
  1.3826 -	// the GB save code is ugly, so rather than convert it all to use gzFiles, just save it to a temp file...
  1.3827 -#define TEMP_SAVE_FNAME ("tempvbawrite.sav")
  1.3828 -	bool retVal = gbWriteBatteryFile(TEMP_SAVE_FNAME, true);
  1.3829 -
  1.3830 -	// ...open the temp file and figure out its size...
  1.3831 -	FILE *fileTemp = fopen(TEMP_SAVE_FNAME, "rb");
  1.3832 -	if (fileTemp == NULL)
  1.3833 -		return false;
  1.3834 -	fseek(fileTemp, 0, SEEK_END);
  1.3835 -	int len = (int) ftell(fileTemp);
  1.3836 -
  1.3837 -	// ...copy over the temp file...
  1.3838 -	char *temp = new char [len];
  1.3839 -	fseek(fileTemp, 0, SEEK_SET);
  1.3840 -	if (fread(temp, len, 1, fileTemp) != 1)
  1.3841 -	{
  1.3842 -		delete [] temp;
  1.3843 -		fclose(fileTemp);
  1.3844 -		return false;
  1.3845 -	}
  1.3846 -	fclose(fileTemp);
  1.3847 -	utilGzWrite(gzfile, temp, len);
  1.3848 -	delete [] temp;
  1.3849 -
  1.3850 -	// ... and delete the temp file
  1.3851 -	remove(TEMP_SAVE_FNAME);
  1.3852 -#undef TEMP_SAVE_FNAME
  1.3853 -
  1.3854 -	return retVal;
  1.3855 -}
  1.3856 -
  1.3857 -bool gbReadBatteryFile(const char *file)
  1.3858 -{
  1.3859 -	bool res = false;
  1.3860 -	if (gbBattery)
  1.3861 -	{
  1.3862 -		int type = gbRom[0x147];
  1.3863 -
  1.3864 -		switch (type)
  1.3865 -		{
  1.3866 -		case 0x03:
  1.3867 -			res = gbReadSaveMBC1(file);
  1.3868 -			break;
  1.3869 -		case 0x06:
  1.3870 -			res = gbReadSaveMBC2(file);
  1.3871 -			break;
  1.3872 -		case 0x0f:
  1.3873 -		case 0x10:
  1.3874 -		case 0x13:
  1.3875 -			if (!gbReadSaveMBC3(file))
  1.3876 -			{
  1.3877 -				struct tm *lt;
  1.3878 -				time_t tmp; //Small kludge to get it working on some systems where time_t has size 8.
  1.3879 -
  1.3880 -				if (VBAMovieActive() || VBAMovieLoading())
  1.3881 -				{
  1.3882 -					gbDataMBC3.mapperLastTime = VBAMovieGetId() + VBAMovieGetFrameCounter() / 60;
  1.3883 -					lt = gmtime(&tmp);
  1.3884 -					gbDataMBC3.mapperLastTime=(u32)tmp;
  1.3885 -				}
  1.3886 -				else
  1.3887 -				{
  1.3888 -					time(&tmp);
  1.3889 -					gbDataMBC3.mapperLastTime=(u32)tmp;
  1.3890 -					lt = localtime(&tmp);
  1.3891 -				}
  1.3892 -				systemScreenMessage(ctime(&tmp), 4);
  1.3893 -				gbDataMBC3.mapperLastTime=(u32)tmp;
  1.3894 -
  1.3895 -				gbDataMBC3.mapperSeconds = lt->tm_sec;
  1.3896 -				gbDataMBC3.mapperMinutes = lt->tm_min;
  1.3897 -				gbDataMBC3.mapperHours	 = lt->tm_hour;
  1.3898 -				gbDataMBC3.mapperDays	 = lt->tm_yday & 255;
  1.3899 -				gbDataMBC3.mapperControl = (gbDataMBC3.mapperControl & 0xfe) |
  1.3900 -				                           (lt->tm_yday > 255 ? 1 : 0);
  1.3901 -				res = false;
  1.3902 -				break;
  1.3903 -			}
  1.3904 -			time_t tmp;
  1.3905 -			systemScreenMessage(ctime(&tmp), 4);
  1.3906 -			gbDataMBC3.mapperLastTime=(u32)tmp;
  1.3907 -			res = true;
  1.3908 -			break;
  1.3909 -		case 0x1b:
  1.3910 -		case 0x1e:
  1.3911 -			res = gbReadSaveMBC5(file);
  1.3912 -			break;
  1.3913 -		case 0x22:
  1.3914 -			res = gbReadSaveMBC7(file);
  1.3915 -		case 0xff:
  1.3916 -			res = gbReadSaveMBC1(file);
  1.3917 -			break;
  1.3918 -		}
  1.3919 -	}
  1.3920 -	systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED;
  1.3921 -	return res;
  1.3922 -}
  1.3923 -
  1.3924 -bool gbReadBatteryFromStream(gzFile gzfile)
  1.3925 -{
  1.3926 -	// the GB save code is ugly, so rather than convert it all to use gzFiles, just copy it to temp RAM...
  1.3927 -#define TEMP_SAVE_FNAME ("tempvbaread.sav")
  1.3928 -	int	  pos	 = gztell(gzfile);
  1.3929 -	int	  buflen = 1024;
  1.3930 -	// ...make a temp file and write it there...
  1.3931 -	FILE *fileTemp = fopen(TEMP_SAVE_FNAME, "wb");
  1.3932 -	if (fileTemp == NULL)
  1.3933 -		return false;
  1.3934 -	int gzDeflated;
  1.3935 -	char *temp	 = new char [buflen];
  1.3936 -	while ((gzDeflated = utilGzRead(gzfile, temp, buflen)) != 0)
  1.3937 -	{
  1.3938 -		if (gzDeflated == -1 || fwrite(temp, gzDeflated, 1, fileTemp) != 1)
  1.3939 -		{
  1.3940 -			delete [] temp;
  1.3941 -			fclose(fileTemp);
  1.3942 -			gzseek(gzfile, pos, SEEK_SET); /// FIXME: leaves pos in gzfile before save instead of after it (everything that
  1.3943 -			                               // calls this right now does a seek afterwards so it doesn't matter for now, but it's
  1.3944 -			                               // still bad)
  1.3945 -			return false;
  1.3946 -		}
  1.3947 -	}
  1.3948 -	gzseek(gzfile, pos, SEEK_SET); /// FIXME: leaves pos in gzfile before save instead of after it (everything that calls this
  1.3949 -	                               // right now does a seek afterwards so it doesn't matter for now, but it's still bad)
  1.3950 -	fclose(fileTemp);
  1.3951 -	delete [] temp;
  1.3952 -
  1.3953 -	// ... load from the temp file...
  1.3954 -	bool retVal = gbReadBatteryFile(TEMP_SAVE_FNAME);
  1.3955 -
  1.3956 -	// ... and delete the temp file
  1.3957 -	remove(TEMP_SAVE_FNAME);
  1.3958 -#undef TEMP_SAVE_FNAME
  1.3959 -
  1.3960 -	return retVal;
  1.3961 -}
  1.3962 -
  1.3963 -bool gbReadGSASnapshot(const char *fileName)
  1.3964 -{
  1.3965 -	FILE *file = fopen(fileName, "rb");
  1.3966 -
  1.3967 -	if (!file)
  1.3968 -	{
  1.3969 -		systemMessage(MSG_CANNOT_OPEN_FILE, N_("Cannot open file %s"), fileName);
  1.3970 -		return false;
  1.3971 -	}
  1.3972 -
  1.3973 -	//  long size = ftell(file);
  1.3974 -	fseek(file, 0x4, SEEK_SET);
  1.3975 -	char buffer[16];
  1.3976 -	char buffer2[16];
  1.3977 -	fread(buffer, 1, 15, file);
  1.3978 -	buffer[15] = 0;
  1.3979 -	memcpy(buffer2, &gbRom[0x134], 15);
  1.3980 -	buffer2[15] = 0;
  1.3981 -	if (memcmp(buffer, buffer2, 15))
  1.3982 -	{
  1.3983 -		systemMessage(MSG_CANNOT_IMPORT_SNAPSHOT_FOR,
  1.3984 -		              N_("Cannot import snapshot for %s. Current game is %s"),
  1.3985 -		              buffer,
  1.3986 -		              buffer2);
  1.3987 -		fclose(file);
  1.3988 -		return false;
  1.3989 -	}
  1.3990 -	fseek(file, 0x13, SEEK_SET);
  1.3991 -	int read   = 0;
  1.3992 -	int toRead = 0;
  1.3993 -	switch (gbRom[0x147])
  1.3994 +  if (gbBattery)
  1.3995 +    {
  1.3996 +      int type = gbRom[0x147];
  1.3997 +
  1.3998 +      switch (type)
  1.3999  	{
  1.4000  	case 0x03:
  1.4001 +	  gbWriteSaveMBC1(file);
  1.4002 +	  break;
  1.4003 +	case 0x06:
  1.4004 +	  gbWriteSaveMBC2(file);
  1.4005 +	  break;
  1.4006  	case 0x0f:
  1.4007  	case 0x10:
  1.4008  	case 0x13:
  1.4009 +	  gbWriteSaveMBC3(file, extendedSave);
  1.4010 +	  break;
  1.4011  	case 0x1b:
  1.4012  	case 0x1e:
  1.4013 +	  gbWriteSaveMBC5(file);
  1.4014 +	  break;
  1.4015 +	case 0x22:
  1.4016 +	  gbWriteSaveMBC7(file);
  1.4017 +	  break;
  1.4018  	case 0xff:
  1.4019 -		read   = fread(gbRam, 1, gbRamSize, file);
  1.4020 -		toRead = gbRamSize;
  1.4021 -		break;
  1.4022 +	  gbWriteSaveMBC1(file);
  1.4023 +	  break;
  1.4024 +	}
  1.4025 +    }
  1.4026 +  return true;
  1.4027 +}
  1.4028 +
  1.4029 +bool gbWriteBatteryFile(const char *file)
  1.4030 +{
  1.4031 +  gbWriteBatteryFile(file, true);
  1.4032 +  return true;
  1.4033 +}
  1.4034 +
  1.4035 +bool gbWriteBatteryToStream(gzFile gzfile)
  1.4036 +{
  1.4037 +  // the GB save code is ugly, so rather than convert it all to use gzFiles, just save it to a temp file...
  1.4038 +#define TEMP_SAVE_FNAME ("tempvbawrite.sav")
  1.4039 +  bool retVal = gbWriteBatteryFile(TEMP_SAVE_FNAME, true);
  1.4040 +
  1.4041 +  // ...open the temp file and figure out its size...
  1.4042 +  FILE *fileTemp = fopen(TEMP_SAVE_FNAME, "rb");
  1.4043 +  if (fileTemp == NULL)
  1.4044 +    return false;
  1.4045 +  fseek(fileTemp, 0, SEEK_END);
  1.4046 +  int len = (int) ftell(fileTemp);
  1.4047 +
  1.4048 +  // ...copy over the temp file...
  1.4049 +  char *temp = new char [len];
  1.4050 +  fseek(fileTemp, 0, SEEK_SET);
  1.4051 +  if (fread(temp, len, 1, fileTemp) != 1)
  1.4052 +    {
  1.4053 +      delete [] temp;
  1.4054 +      fclose(fileTemp);
  1.4055 +      return false;
  1.4056 +    }
  1.4057 +  fclose(fileTemp);
  1.4058 +  utilGzWrite(gzfile, temp, len);
  1.4059 +  delete [] temp;
  1.4060 +
  1.4061 +  // ... and delete the temp file
  1.4062 +  remove(TEMP_SAVE_FNAME);
  1.4063 +#undef TEMP_SAVE_FNAME
  1.4064 +
  1.4065 +  return retVal;
  1.4066 +}
  1.4067 +
  1.4068 +bool gbReadBatteryFile(const char *file)
  1.4069 +{
  1.4070 +  bool res = false;
  1.4071 +  if (gbBattery)
  1.4072 +    {
  1.4073 +      int type = gbRom[0x147];
  1.4074 +
  1.4075 +      switch (type)
  1.4076 +	{
  1.4077 +	case 0x03:
  1.4078 +	  res = gbReadSaveMBC1(file);
  1.4079 +	  break;
  1.4080  	case 0x06:
  1.4081 +	  res = gbReadSaveMBC2(file);
  1.4082 +	  break;
  1.4083 +	case 0x0f:
  1.4084 +	case 0x10:
  1.4085 +	case 0x13:
  1.4086 +	  if (!gbReadSaveMBC3(file))
  1.4087 +	    {
  1.4088 +	      struct tm *lt;
  1.4089 +	      time_t tmp; //Small kludge to get it working on some systems where time_t has size 8.
  1.4090 +
  1.4091 +	      if (VBAMovieActive() || VBAMovieLoading())
  1.4092 +		{
  1.4093 +		  gbDataMBC3.mapperLastTime = VBAMovieGetId() + VBAMovieGetFrameCounter() / 60;
  1.4094 +		  lt = gmtime(&tmp);
  1.4095 +		  gbDataMBC3.mapperLastTime=(u32)tmp;
  1.4096 +		}
  1.4097 +	      else
  1.4098 +		{
  1.4099 +		  time(&tmp);
  1.4100 +		  gbDataMBC3.mapperLastTime=(u32)tmp;
  1.4101 +		  lt = localtime(&tmp);
  1.4102 +		}
  1.4103 +	      systemScreenMessage(ctime(&tmp), 4);
  1.4104 +	      gbDataMBC3.mapperLastTime=(u32)tmp;
  1.4105 +
  1.4106 +	      gbDataMBC3.mapperSeconds = lt->tm_sec;
  1.4107 +	      gbDataMBC3.mapperMinutes = lt->tm_min;
  1.4108 +	      gbDataMBC3.mapperHours	 = lt->tm_hour;
  1.4109 +	      gbDataMBC3.mapperDays	 = lt->tm_yday & 255;
  1.4110 +	      gbDataMBC3.mapperControl = (gbDataMBC3.mapperControl & 0xfe) |
  1.4111 +		(lt->tm_yday > 255 ? 1 : 0);
  1.4112 +	      res = false;
  1.4113 +	      break;
  1.4114 +	    }
  1.4115 +	  time_t tmp;
  1.4116 +	  systemScreenMessage(ctime(&tmp), 4);
  1.4117 +	  gbDataMBC3.mapperLastTime=(u32)tmp;
  1.4118 +	  res = true;
  1.4119 +	  break;
  1.4120 +	case 0x1b:
  1.4121 +	case 0x1e:
  1.4122 +	  res = gbReadSaveMBC5(file);
  1.4123 +	  break;
  1.4124  	case 0x22:
  1.4125 -		read   = fread(&gbMemory[0xa000], 1, 256, file);
  1.4126 -		toRead = 256;
  1.4127 -		break;
  1.4128 -	default:
  1.4129 -		systemMessage(MSG_UNSUPPORTED_SNAPSHOT_FILE,
  1.4130 -		              N_("Unsupported snapshot file %s"),
  1.4131 -		              fileName);
  1.4132 -		fclose(file);
  1.4133 -		return false;
  1.4134 +	  res = gbReadSaveMBC7(file);
  1.4135 +	case 0xff:
  1.4136 +	  res = gbReadSaveMBC1(file);
  1.4137 +	  break;
  1.4138  	}
  1.4139 -	fclose(file);
  1.4140 -	gbReset();
  1.4141 -	return true;
  1.4142 +    }
  1.4143 +  systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED;
  1.4144 +  return res;
  1.4145  }
  1.4146  
  1.4147 +bool gbReadBatteryFromStream(gzFile gzfile)
  1.4148 +{
  1.4149 +  // the GB save code is ugly, so rather than convert it all to use gzFiles, just copy it to temp RAM...
  1.4150 +#define TEMP_SAVE_FNAME ("tempvbaread.sav")
  1.4151 +  int	  pos	 = gztell(gzfile);
  1.4152 +  int	  buflen = 1024;
  1.4153 +  // ...make a temp file and write it there...
  1.4154 +  FILE *fileTemp = fopen(TEMP_SAVE_FNAME, "wb");
  1.4155 +  if (fileTemp == NULL)
  1.4156 +    return false;
  1.4157 +  int gzDeflated;
  1.4158 +  char *temp	 = new char [buflen];
  1.4159 +  while ((gzDeflated = utilGzRead(gzfile, temp, buflen)) != 0)
  1.4160 +    {
  1.4161 +      if (gzDeflated == -1 || fwrite(temp, gzDeflated, 1, fileTemp) != 1)
  1.4162 +	{
  1.4163 +	  delete [] temp;
  1.4164 +	  fclose(fileTemp);
  1.4165 +	  gzseek(gzfile, pos, SEEK_SET); /// FIXME: leaves pos in gzfile before save instead of after it (everything that
  1.4166 +	  // calls this right now does a seek afterwards so it doesn't matter for now, but it's
  1.4167 +	  // still bad)
  1.4168 +	  return false;
  1.4169 +	}
  1.4170 +    }
  1.4171 +  gzseek(gzfile, pos, SEEK_SET); /// FIXME: leaves pos in gzfile before save instead of after it (everything that calls this
  1.4172 +  // right now does a seek afterwards so it doesn't matter for now, but it's still bad)
  1.4173 +  fclose(fileTemp);
  1.4174 +  delete [] temp;
  1.4175 +
  1.4176 +  // ... load from the temp file...
  1.4177 +  bool retVal = gbReadBatteryFile(TEMP_SAVE_FNAME);
  1.4178 +
  1.4179 +  // ... and delete the temp file
  1.4180 +  remove(TEMP_SAVE_FNAME);
  1.4181 +#undef TEMP_SAVE_FNAME
  1.4182 +
  1.4183 +  return retVal;
  1.4184 +}
  1.4185 +
  1.4186 +bool gbReadGSASnapshot(const char *fileName)
  1.4187 +{
  1.4188 +  FILE *file = fopen(fileName, "rb");
  1.4189 +
  1.4190 +  if (!file)
  1.4191 +    {
  1.4192 +      systemMessage(MSG_CANNOT_OPEN_FILE, N_("Cannot open file %s"), fileName);
  1.4193 +      return false;
  1.4194 +    }
  1.4195 +
  1.4196 +  //  long size = ftell(file);
  1.4197 +  fseek(file, 0x4, SEEK_SET);
  1.4198 +  char buffer[16];
  1.4199 +  char buffer2[16];
  1.4200 +  fread(buffer, 1, 15, file);
  1.4201 +  buffer[15] = 0;
  1.4202 +  memcpy(buffer2, &gbRom[0x134], 15);
  1.4203 +  buffer2[15] = 0;
  1.4204 +  if (memcmp(buffer, buffer2, 15))
  1.4205 +    {
  1.4206 +      systemMessage(MSG_CANNOT_IMPORT_SNAPSHOT_FOR,
  1.4207 +		    N_("Cannot import snapshot for %s. Current game is %s"),
  1.4208 +		    buffer,
  1.4209 +		    buffer2);
  1.4210 +      fclose(file);
  1.4211 +      return false;
  1.4212 +    }
  1.4213 +  fseek(file, 0x13, SEEK_SET);
  1.4214 +  int read   = 0;
  1.4215 +  int toRead = 0;
  1.4216 +  switch (gbRom[0x147])
  1.4217 +    {
  1.4218 +    case 0x03:
  1.4219 +    case 0x0f:
  1.4220 +    case 0x10:
  1.4221 +    case 0x13:
  1.4222 +    case 0x1b:
  1.4223 +    case 0x1e:
  1.4224 +    case 0xff:
  1.4225 +      read   = fread(gbRam, 1, gbRamSize, file);
  1.4226 +      toRead = gbRamSize;
  1.4227 +      break;
  1.4228 +    case 0x06:
  1.4229 +    case 0x22:
  1.4230 +      read   = fread(&gbMemory[0xa000], 1, 256, file);
  1.4231 +      toRead = 256;
  1.4232 +      break;
  1.4233 +    default:
  1.4234 +      systemMessage(MSG_UNSUPPORTED_SNAPSHOT_FILE,
  1.4235 +		    N_("Unsupported snapshot file %s"),
  1.4236 +		    fileName);
  1.4237 +      fclose(file);
  1.4238 +      return false;
  1.4239 +    }
  1.4240 +  fclose(file);
  1.4241 +  gbReset();
  1.4242 +  return true;
  1.4243 +}
  1.4244 +
  1.4245  variable_desc gbSaveGameStruct[] =
  1.4246 -{
  1.4247 -	{ &PC.W,					   sizeof(u16)						 },
  1.4248 -	{ &SP.W,					   sizeof(u16)						 },
  1.4249 -	{ &AF.W,					   sizeof(u16)						 },
  1.4250 -	{ &BC.W,					   sizeof(u16)						 },
  1.4251 -	{ &DE.W,					   sizeof(u16)						 },
  1.4252 -	{ &HL.W,					   sizeof(u16)						 },
  1.4253 -	{ &IFF,						   sizeof(u8)						 },
  1.4254 -	{ &GBLCD_MODE_0_CLOCK_TICKS,   sizeof(int32)					 },
  1.4255 -	{ &GBLCD_MODE_1_CLOCK_TICKS,   sizeof(int32)					 },
  1.4256 -	{ &GBLCD_MODE_2_CLOCK_TICKS,   sizeof(int32)					 },
  1.4257 -	{ &GBLCD_MODE_3_CLOCK_TICKS,   sizeof(int32)					 },
  1.4258 -	{ &GBDIV_CLOCK_TICKS,		   sizeof(int32)					 },
  1.4259 -	{ &GBLY_INCREMENT_CLOCK_TICKS, sizeof(int32)					 },
  1.4260 -	{ &GBTIMER_MODE_0_CLOCK_TICKS, sizeof(int32)					 },
  1.4261 -	{ &GBTIMER_MODE_1_CLOCK_TICKS, sizeof(int32)					 },
  1.4262 -	{ &GBTIMER_MODE_2_CLOCK_TICKS, sizeof(int32)					 },
  1.4263 -	{ &GBTIMER_MODE_3_CLOCK_TICKS, sizeof(int32)					 },
  1.4264 -	{ &GBSERIAL_CLOCK_TICKS,	   sizeof(int32)					 },
  1.4265 -	{ &GBSYNCHRONIZE_CLOCK_TICKS,  sizeof(int32)					 },
  1.4266 -	{ &gbDivTicks,				   sizeof(int32)					 },
  1.4267 -	{ &gbLcdMode,				   sizeof(int32)					 },
  1.4268 -	{ &gbLcdTicks,				   sizeof(int32)					 },
  1.4269 -	{ &gbLcdLYIncrementTicks,	   sizeof(int32)					 },
  1.4270 -	{ &gbTimerTicks,			   sizeof(int32)					 },
  1.4271 -	{ &gbTimerClockTicks,		   sizeof(int32)					 },
  1.4272 -	{ &gbSerialTicks,			   sizeof(int32)					 },
  1.4273 -	{ &gbSerialBits,			   sizeof(int32)					 },
  1.4274 -	{ &gbInterrupt,				   sizeof(int32)					 },
  1.4275 -	{ &gbInterruptWait,			   sizeof(int32)					 },
  1.4276 -	{ &gbSynchronizeTicks,		   sizeof(int32)					 },
  1.4277 -	{ &gbTimerOn,				   sizeof(int32)					 },
  1.4278 -	{ &gbTimerMode,				   sizeof(int32)					 },
  1.4279 -	{ &gbSerialOn,				   sizeof(int32)					 },
  1.4280 -	{ &gbWindowLine,			   sizeof(int32)					 },
  1.4281 -	{ &gbCgbMode,				   sizeof(int32)					 },
  1.4282 -	{ &gbVramBank,				   sizeof(int32)					 },
  1.4283 -	{ &gbWramBank,				   sizeof(int32)					 },
  1.4284 -	{ &gbHdmaSource,			   sizeof(int32)					 },
  1.4285 -	{ &gbHdmaDestination,		   sizeof(int32)					 },
  1.4286 -	{ &gbHdmaBytes,				   sizeof(int32)					 },
  1.4287 -	{ &gbHdmaOn,				   sizeof(int32)					 },
  1.4288 -	{ &gbSpeed,					   sizeof(int32)					 },
  1.4289 -	{ &gbSgbMode,				   sizeof(int32)					 },
  1.4290 -	{ &register_DIV,			   sizeof(u8)						 },
  1.4291 -	{ &register_TIMA,			   sizeof(u8)						 },
  1.4292 -	{ &register_TMA,			   sizeof(u8)						 },
  1.4293 -	{ &register_TAC,			   sizeof(u8)						 },
  1.4294 -	{ &register_IF,				   sizeof(u8)						 },
  1.4295 -	{ &register_LCDC,			   sizeof(u8)						 },
  1.4296 -	{ &register_STAT,			   sizeof(u8)						 },
  1.4297 -	{ &register_SCY,			   sizeof(u8)						 },
  1.4298 -	{ &register_SCX,			   sizeof(u8)						 },
  1.4299 -	{ &register_LY,				   sizeof(u8)						 },
  1.4300 -	{ &register_LYC,			   sizeof(u8)						 },
  1.4301 -	{ &register_DMA,			   sizeof(u8)						 },
  1.4302 -	{ &register_WY,				   sizeof(u8)						 },
  1.4303 -	{ &register_WX,				   sizeof(u8)						 },
  1.4304 -	{ &register_VBK,			   sizeof(u8)						 },
  1.4305 -	{ &register_HDMA1,			   sizeof(u8)						 },
  1.4306 -	{ &register_HDMA2,			   sizeof(u8)						 },
  1.4307 -	{ &register_HDMA3,			   sizeof(u8)						 },
  1.4308 -	{ &register_HDMA4,			   sizeof(u8)						 },
  1.4309 -	{ &register_HDMA5,			   sizeof(u8)						 },
  1.4310 -	{ &register_SVBK,			   sizeof(u8)						 },
  1.4311 -	{ &register_IE,				   sizeof(u8)						 },
  1.4312 -	{ &gbBgp[0],				   sizeof(u8)						 },
  1.4313 -	{ &gbBgp[1],				   sizeof(u8)						 },
  1.4314 -	{ &gbBgp[2],				   sizeof(u8)						 },
  1.4315 -	{ &gbBgp[3],				   sizeof(u8)						 },
  1.4316 -	{ &gbObp0[0],				   sizeof(u8)						 },
  1.4317 -	{ &gbObp0[1],				   sizeof(u8)						 },
  1.4318 -	{ &gbObp0[2],				   sizeof(u8)						 },
  1.4319 -	{ &gbObp0[3],				   sizeof(u8)						 },
  1.4320 -	{ &gbObp1[0],				   sizeof(u8)						 },
  1.4321 -	{ &gbObp1[1],				   sizeof(u8)						 },
  1.4322 -	{ &gbObp1[2],				   sizeof(u8)						 },
  1.4323 -	{ &gbObp1[3],				   sizeof(u8)						 },
  1.4324 -	{ NULL,						   0								 }
  1.4325 -};
  1.4326 +  {
  1.4327 +    { &PC.W,					   sizeof(u16)						 },
  1.4328 +    { &SP.W,					   sizeof(u16)						 },
  1.4329 +    { &AF.W,					   sizeof(u16)						 },
  1.4330 +    { &BC.W,					   sizeof(u16)						 },
  1.4331 +    { &DE.W,					   sizeof(u16)						 },
  1.4332 +    { &HL.W,					   sizeof(u16)						 },
  1.4333 +    { &IFF,						   sizeof(u8)						 },
  1.4334 +    { &GBLCD_MODE_0_CLOCK_TICKS,   sizeof(int32)					 },
  1.4335 +    { &GBLCD_MODE_1_CLOCK_TICKS,   sizeof(int32)					 },
  1.4336 +    { &GBLCD_MODE_2_CLOCK_TICKS,   sizeof(int32)					 },
  1.4337 +    { &GBLCD_MODE_3_CLOCK_TICKS,   sizeof(int32)					 },
  1.4338 +    { &GBDIV_CLOCK_TICKS,		   sizeof(int32)					 },
  1.4339 +    { &GBLY_INCREMENT_CLOCK_TICKS, sizeof(int32)					 },
  1.4340 +    { &GBTIMER_MODE_0_CLOCK_TICKS, sizeof(int32)					 },
  1.4341 +    { &GBTIMER_MODE_1_CLOCK_TICKS, sizeof(int32)					 },
  1.4342 +    { &GBTIMER_MODE_2_CLOCK_TICKS, sizeof(int32)					 },
  1.4343 +    { &GBTIMER_MODE_3_CLOCK_TICKS, sizeof(int32)					 },
  1.4344 +    { &GBSERIAL_CLOCK_TICKS,	   sizeof(int32)					 },
  1.4345 +    { &GBSYNCHRONIZE_CLOCK_TICKS,  sizeof(int32)					 },
  1.4346 +    { &gbDivTicks,				   sizeof(int32)					 },
  1.4347 +    { &gbLcdMode,				   sizeof(int32)					 },
  1.4348 +    { &gbLcdTicks,				   sizeof(int32)					 },
  1.4349 +    { &gbLcdLYIncrementTicks,	   sizeof(int32)					 },
  1.4350 +    { &gbTimerTicks,			   sizeof(int32)					 },
  1.4351 +    { &gbTimerClockTicks,		   sizeof(int32)					 },
  1.4352 +    { &gbSerialTicks,			   sizeof(int32)					 },
  1.4353 +    { &gbSerialBits,			   sizeof(int32)					 },
  1.4354 +    { &gbInterrupt,				   sizeof(int32)					 },
  1.4355 +    { &gbInterruptWait,			   sizeof(int32)					 },
  1.4356 +    { &gbSynchronizeTicks,		   sizeof(int32)					 },
  1.4357 +    { &gbTimerOn,				   sizeof(int32)					 },
  1.4358 +    { &gbTimerMode,				   sizeof(int32)					 },
  1.4359 +    { &gbSerialOn,				   sizeof(int32)					 },
  1.4360 +    { &gbWindowLine,			   sizeof(int32)					 },
  1.4361 +    { &gbCgbMode,				   sizeof(int32)					 },
  1.4362 +    { &gbVramBank,				   sizeof(int32)					 },
  1.4363 +    { &gbWramBank,				   sizeof(int32)					 },
  1.4364 +    { &gbHdmaSource,			   sizeof(int32)					 },
  1.4365 +    { &gbHdmaDestination,		   sizeof(int32)					 },
  1.4366 +    { &gbHdmaBytes,				   sizeof(int32)					 },
  1.4367 +    { &gbHdmaOn,				   sizeof(int32)					 },
  1.4368 +    { &gbSpeed,					   sizeof(int32)					 },
  1.4369 +    { &gbSgbMode,				   sizeof(int32)					 },
  1.4370 +    { &register_DIV,			   sizeof(u8)						 },
  1.4371 +    { &register_TIMA,			   sizeof(u8)						 },
  1.4372 +    { &register_TMA,			   sizeof(u8)						 },
  1.4373 +    { &register_TAC,			   sizeof(u8)						 },
  1.4374 +    { &register_IF,				   sizeof(u8)						 },
  1.4375 +    { &register_LCDC,			   sizeof(u8)						 },
  1.4376 +    { &register_STAT,			   sizeof(u8)						 },
  1.4377 +    { &register_SCY,			   sizeof(u8)						 },
  1.4378 +    { &register_SCX,			   sizeof(u8)						 },
  1.4379 +    { &register_LY,				   sizeof(u8)						 },
  1.4380 +    { &register_LYC,			   sizeof(u8)						 },
  1.4381 +    { &register_DMA,			   sizeof(u8)						 },
  1.4382 +    { &register_WY,				   sizeof(u8)						 },
  1.4383 +    { &register_WX,				   sizeof(u8)						 },
  1.4384 +    { &register_VBK,			   sizeof(u8)						 },
  1.4385 +    { &register_HDMA1,			   sizeof(u8)						 },
  1.4386 +    { &register_HDMA2,			   sizeof(u8)						 },
  1.4387 +    { &register_HDMA3,			   sizeof(u8)						 },
  1.4388 +    { &register_HDMA4,			   sizeof(u8)						 },
  1.4389 +    { &register_HDMA5,			   sizeof(u8)						 },
  1.4390 +    { &register_SVBK,			   sizeof(u8)						 },
  1.4391 +    { &register_IE,				   sizeof(u8)						 },
  1.4392 +    { &gbBgp[0],				   sizeof(u8)						 },
  1.4393 +    { &gbBgp[1],				   sizeof(u8)						 },
  1.4394 +    { &gbBgp[2],				   sizeof(u8)						 },
  1.4395 +    { &gbBgp[3],				   sizeof(u8)						 },
  1.4396 +    { &gbObp0[0],				   sizeof(u8)						 },
  1.4397 +    { &gbObp0[1],				   sizeof(u8)						 },
  1.4398 +    { &gbObp0[2],				   sizeof(u8)						 },
  1.4399 +    { &gbObp0[3],				   sizeof(u8)						 },
  1.4400 +    { &gbObp1[0],				   sizeof(u8)						 },
  1.4401 +    { &gbObp1[1],				   sizeof(u8)						 },
  1.4402 +    { &gbObp1[2],				   sizeof(u8)						 },
  1.4403 +    { &gbObp1[3],				   sizeof(u8)						 },
  1.4404 +    { NULL,						   0								 }
  1.4405 +  };
  1.4406  
  1.4407  bool gbWriteSaveStateToStream(gzFile gzFile)
  1.4408  {
  1.4409 -	utilWriteInt(gzFile, GBSAVE_GAME_VERSION);
  1.4410 -
  1.4411 -	utilGzWrite(gzFile, &gbRom[0x134], 15);
  1.4412 -
  1.4413 -	utilWriteData(gzFile, gbSaveGameStruct);
  1.4414 -
  1.4415 -	utilGzWrite(gzFile, &IFF, 2);
  1.4416 -
  1.4417 -	if (gbSgbMode)
  1.4418 -	{
  1.4419 -		gbSgbSaveGame(gzFile);
  1.4420 -	}
  1.4421 -
  1.4422 -	utilGzWrite(gzFile, &gbDataMBC1, sizeof(gbDataMBC1));
  1.4423 -	utilGzWrite(gzFile, &gbDataMBC2, sizeof(gbDataMBC2));
  1.4424 -	//assert(sizeof(time_t) == 4);
  1.4425 -	utilGzWrite(gzFile, &gbDataMBC3, sizeof(gbDataMBC3));
  1.4426 -	utilGzWrite(gzFile, &gbDataMBC5, sizeof(gbDataMBC5));
  1.4427 -	utilGzWrite(gzFile, &gbDataHuC1, sizeof(gbDataHuC1));
  1.4428 -	utilGzWrite(gzFile, &gbDataHuC3, sizeof(gbDataHuC3));
  1.4429 -
  1.4430 -	// yes, this definitely needs to be saved, or loading paused games will show a black screen
  1.4431 -	// this is also necessary to be consistent with what the GBA saving does
  1.4432 -	utilGzWrite(gzFile, pix, 4 * 257 * 226);
  1.4433 -
  1.4434 -	utilGzWrite(gzFile, gbPalette, 128 * sizeof(u16));
  1.4435 -	// todo: remove
  1.4436 -	utilGzWrite(gzFile, gbPalette, 128 * sizeof(u16));
  1.4437 -
  1.4438 -	utilGzWrite(gzFile, &gbMemory[0x8000], 0x8000);
  1.4439 -
  1.4440 -	if (gbRamSize && gbRam)
  1.4441 -	{
  1.4442 -		utilGzWrite(gzFile, gbRam, gbRamSize);
  1.4443 -	}
  1.4444 -
  1.4445 -	if (gbCgbMode)
  1.4446 -	{
  1.4447 -		utilGzWrite(gzFile, gbVram, 0x4000);
  1.4448 -		utilGzWrite(gzFile, gbWram, 0x8000);
  1.4449 -	}
  1.4450 -
  1.4451 -	gbSoundSaveGame(gzFile);
  1.4452 -
  1.4453 -	gbCheatsSaveGame(gzFile);
  1.4454 -
  1.4455 -	// new to re-recording version:
  1.4456 -	{
  1.4457 -		extern int32 sensorX, sensorY;
  1.4458 -		utilGzWrite(gzFile, &sensorX, sizeof(sensorX));
  1.4459 -		utilGzWrite(gzFile, &sensorY, sizeof(sensorY));
  1.4460 -		utilGzWrite(gzFile, gbJoymask, 4 * sizeof(*gbJoymask)); // this has to be saved or old input will incorrectly get
  1.4461 -		                                                        // carried
  1.4462 -		                                                        // back on loading a snapshot!
  1.4463 -
  1.4464 -		bool8 movieActive = VBAMovieActive();
  1.4465 -		utilGzWrite(gzFile, &movieActive, sizeof(movieActive));
  1.4466 -		if (movieActive)
  1.4467 -		{
  1.4468 -			uint8 *movie_freeze_buf	 = NULL;
  1.4469 -			uint32 movie_freeze_size = 0;
  1.4470 -
  1.4471 -			VBAMovieFreeze(&movie_freeze_buf, &movie_freeze_size);
  1.4472 -			if (movie_freeze_buf)
  1.4473 -			{
  1.4474 -				utilGzWrite(gzFile, &movie_freeze_size, sizeof(movie_freeze_size));
  1.4475 -				utilGzWrite(gzFile, movie_freeze_buf, movie_freeze_size);
  1.4476 -				delete [] movie_freeze_buf;
  1.4477 -			}
  1.4478 -			else
  1.4479 -			{
  1.4480 -				systemMessage(0, N_("Failed to save movie snapshot."));
  1.4481 -				return false;
  1.4482 -			}
  1.4483 -		}
  1.4484 -		utilGzWrite(gzFile, &GBSystemCounters.frameCount, sizeof(GBSystemCounters.frameCount));
  1.4485 -	}
  1.4486 -
  1.4487 -	// new to rerecording 19.4 wip (svn r22+):
  1.4488 -	{
  1.4489 -		utilGzWrite(gzFile, &GBSystemCounters.lagCount, sizeof(GBSystemCounters.lagCount));
  1.4490 -		utilGzWrite(gzFile, &GBSystemCounters.lagged, sizeof(GBSystemCounters.lagged));
  1.4491 -		utilGzWrite(gzFile, &GBSystemCounters.laggedLast, sizeof(GBSystemCounters.laggedLast));
  1.4492 -	}
  1.4493 -
  1.4494 -	return true;
  1.4495 +  utilWriteInt(gzFile, GBSAVE_GAME_VERSION);
  1.4496 +
  1.4497 +  utilGzWrite(gzFile, &gbRom[0x134], 15);
  1.4498 +
  1.4499 +  utilWriteData(gzFile, gbSaveGameStruct);
  1.4500 +
  1.4501 +  utilGzWrite(gzFile, &IFF, 2);
  1.4502 +
  1.4503 +  if (gbSgbMode)
  1.4504 +    {
  1.4505 +      gbSgbSaveGame(gzFile);
  1.4506 +    }
  1.4507 +
  1.4508 +  utilGzWrite(gzFile, &gbDataMBC1, sizeof(gbDataMBC1));
  1.4509 +  utilGzWrite(gzFile, &gbDataMBC2, sizeof(gbDataMBC2));
  1.4510 +  //assert(sizeof(time_t) == 4);
  1.4511 +  utilGzWrite(gzFile, &gbDataMBC3, sizeof(gbDataMBC3));
  1.4512 +  utilGzWrite(gzFile, &gbDataMBC5, sizeof(gbDataMBC5));
  1.4513 +  utilGzWrite(gzFile, &gbDataHuC1, sizeof(gbDataHuC1));
  1.4514 +  utilGzWrite(gzFile, &gbDataHuC3, sizeof(gbDataHuC3));
  1.4515 +
  1.4516 +  // yes, this definitely needs to be saved, or loading paused games will show a black screen
  1.4517 +  // this is also necessary to be consistent with what the GBA saving does
  1.4518 +  utilGzWrite(gzFile, pix, 4 * 257 * 226);
  1.4519 +
  1.4520 +  utilGzWrite(gzFile, gbPalette, 128 * sizeof(u16));
  1.4521 +  // todo: remove
  1.4522 +  utilGzWrite(gzFile, gbPalette, 128 * sizeof(u16));
  1.4523 +
  1.4524 +  utilGzWrite(gzFile, &gbMemory[0x8000], 0x8000);
  1.4525 +
  1.4526 +  if (gbRamSize && gbRam)
  1.4527 +    {
  1.4528 +      utilGzWrite(gzFile, gbRam, gbRamSize);
  1.4529 +    }
  1.4530 +
  1.4531 +  if (gbCgbMode)
  1.4532 +    {
  1.4533 +      utilGzWrite(gzFile, gbVram, 0x4000);
  1.4534 +      utilGzWrite(gzFile, gbWram, 0x8000);
  1.4535 +    }
  1.4536 +
  1.4537 +  gbSoundSaveGame(gzFile);
  1.4538 +
  1.4539 +  gbCheatsSaveGame(gzFile);
  1.4540 +
  1.4541 +  // new to re-recording version:
  1.4542 +  {
  1.4543 +    extern int32 sensorX, sensorY;
  1.4544 +    utilGzWrite(gzFile, &sensorX, sizeof(sensorX));
  1.4545 +    utilGzWrite(gzFile, &sensorY, sizeof(sensorY));
  1.4546 +    utilGzWrite(gzFile, gbJoymask, 4 * sizeof(*gbJoymask)); // this has to be saved or old input will incorrectly get
  1.4547 +    // carried
  1.4548 +    // back on loading a snapshot!
  1.4549 +
  1.4550 +    bool8 movieActive = VBAMovieActive();
  1.4551 +    utilGzWrite(gzFile, &movieActive, sizeof(movieActive));
  1.4552 +    if (movieActive)
  1.4553 +      {
  1.4554 +	uint8 *movie_freeze_buf	 = NULL;
  1.4555 +	uint32 movie_freeze_size = 0;
  1.4556 +
  1.4557 +	VBAMovieFreeze(&movie_freeze_buf, &movie_freeze_size);
  1.4558 +	if (movie_freeze_buf)
  1.4559 +	  {
  1.4560 +	    utilGzWrite(gzFile, &movie_freeze_size, sizeof(movie_freeze_size));
  1.4561 +	    utilGzWrite(gzFile, movie_freeze_buf, movie_freeze_size);
  1.4562 +	    delete [] movie_freeze_buf;
  1.4563 +	  }
  1.4564 +	else
  1.4565 +	  {
  1.4566 +	    systemMessage(0, N_("Failed to save movie snapshot."));
  1.4567 +	    return false;
  1.4568 +	  }
  1.4569 +      }
  1.4570 +    utilGzWrite(gzFile, &GBSystemCounters.frameCount, sizeof(GBSystemCounters.frameCount));
  1.4571 +  }
  1.4572 +
  1.4573 +  // new to rerecording 19.4 wip (svn r22+):
  1.4574 +  {
  1.4575 +    utilGzWrite(gzFile, &GBSystemCounters.lagCount, sizeof(GBSystemCounters.lagCount));
  1.4576 +    utilGzWrite(gzFile, &GBSystemCounters.lagged, sizeof(GBSystemCounters.lagged));
  1.4577 +    utilGzWrite(gzFile, &GBSystemCounters.laggedLast, sizeof(GBSystemCounters.laggedLast));
  1.4578 +  }
  1.4579 +
  1.4580 +  return true;
  1.4581  }
  1.4582  
  1.4583  bool gbWriteMemSaveState(char *memory, int available)
  1.4584  {
  1.4585 -	gzFile gzFile = utilMemGzOpen(memory, available, "w");
  1.4586 -
  1.4587 -	if (gzFile == NULL)
  1.4588 -	{
  1.4589 -		return false;
  1.4590 -	}
  1.4591 -
  1.4592 -	bool res = gbWriteSaveStateToStream(gzFile);
  1.4593 -
  1.4594 -	long pos = utilGzTell(gzFile) + 8;
  1.4595 -
  1.4596 -	if (pos >= (available))
  1.4597 -		res = false;
  1.4598 -
  1.4599 -	utilGzClose(gzFile);
  1.4600 -
  1.4601 -	return res;
  1.4602 +  gzFile gzFile = utilMemGzOpen(memory, available, "w");
  1.4603 +
  1.4604 +  if (gzFile == NULL)
  1.4605 +    {
  1.4606 +      return false;
  1.4607 +    }
  1.4608 +
  1.4609 +  bool res = gbWriteSaveStateToStream(gzFile);
  1.4610 +
  1.4611 +  long pos = utilGzTell(gzFile) + 8;
  1.4612 +
  1.4613 +  if (pos >= (available))
  1.4614 +    res = false;
  1.4615 +
  1.4616 +  utilGzClose(gzFile);
  1.4617 +
  1.4618 +  return res;
  1.4619  }
  1.4620  
  1.4621  bool gbWriteSaveState(const char *name)
  1.4622  {
  1.4623 -	gzFile gzFile = utilGzOpen(name, "wb");
  1.4624 -
  1.4625 -	if (gzFile == NULL)
  1.4626 -		return false;
  1.4627 -
  1.4628 -	bool res = gbWriteSaveStateToStream(gzFile);
  1.4629 -
  1.4630 -	utilGzClose(gzFile);
  1.4631 -	return res;
  1.4632 +  gzFile gzFile = utilGzOpen(name, "wb");
  1.4633 +
  1.4634 +  if (gzFile == NULL)
  1.4635 +    return false;
  1.4636 +
  1.4637 +  bool res = gbWriteSaveStateToStream(gzFile);
  1.4638 +
  1.4639 +  utilGzClose(gzFile);
  1.4640 +  return res;
  1.4641  }
  1.4642  
  1.4643  static int	tempStateID	  = 0;
  1.4644 @@ -2591,1328 +2591,1331 @@
  1.4645  
  1.4646  bool gbReadSaveStateFromStream(gzFile gzFile)
  1.4647  {
  1.4648 -	int	 type;
  1.4649 -	char tempBackupName [128];
  1.4650 -	if (backupSafe)
  1.4651 +  int	 type;
  1.4652 +  char tempBackupName [128];
  1.4653 +  if (backupSafe)
  1.4654 +    {
  1.4655 +      sprintf(tempBackupName, "gbatempsave%d.sav", tempStateID++);
  1.4656 +      gbWriteSaveState(tempBackupName);
  1.4657 +    }
  1.4658 +
  1.4659 +  int version = utilReadInt(gzFile);
  1.4660 +
  1.4661 +  if (version > GBSAVE_GAME_VERSION || version < 0)
  1.4662 +    {
  1.4663 +      systemMessage(MSG_UNSUPPORTED_VB_SGM,
  1.4664 +		    N_("Unsupported VisualBoy save game version %d"), version);
  1.4665 +      goto failedLoadGB;
  1.4666 +    }
  1.4667 +
  1.4668 +  u8 romname[20];
  1.4669 +
  1.4670 +  utilGzRead(gzFile, romname, 15);
  1.4671 +
  1.4672 +  if (memcmp(&gbRom[0x134], romname, 15) != 0)
  1.4673 +    {
  1.4674 +      systemMessage(MSG_CANNOT_LOAD_SGM_FOR,
  1.4675 +		    N_("Cannot load save game for %s. Playing %s"),
  1.4676 +		    romname, &gbRom[0x134]);
  1.4677 +      goto failedLoadGB;
  1.4678 +    }
  1.4679 +
  1.4680 +  utilReadData(gzFile, gbSaveGameStruct);
  1.4681 +
  1.4682 +  if (version >= GBSAVE_GAME_VERSION_7)
  1.4683 +    {
  1.4684 +      utilGzRead(gzFile, &IFF, 2);
  1.4685 +    }
  1.4686 +
  1.4687 +  if (gbSgbMode)
  1.4688 +    {
  1.4689 +      gbSgbReadGame(gzFile, version);
  1.4690 +    }
  1.4691 +  else
  1.4692 +    {
  1.4693 +      gbSgbMask = 0; // loading a game at the wrong time causes no display
  1.4694 +    }
  1.4695 +
  1.4696 +  utilGzRead(gzFile, &gbDataMBC1, sizeof(gbDataMBC1));
  1.4697 +  utilGzRead(gzFile, &gbDataMBC2, sizeof(gbDataMBC2));
  1.4698 +  if (version < GBSAVE_GAME_VERSION_4)
  1.4699 +    // prior to version 4, there was no adjustment for the time the game
  1.4700 +    // was last played, so we have less to read. This needs update if the
  1.4701 +    // structure changes again.
  1.4702 +    utilGzRead(gzFile, &gbDataMBC3, sizeof(int32) * 10);
  1.4703 +  else
  1.4704 +    {
  1.4705 +      //assert(sizeof(time_t) == 4);
  1.4706 +      utilGzRead(gzFile, &gbDataMBC3, sizeof(gbDataMBC3));
  1.4707 +    }
  1.4708 +  utilGzRead(gzFile, &gbDataMBC5, sizeof(gbDataMBC5));
  1.4709 +  utilGzRead(gzFile, &gbDataHuC1, sizeof(gbDataHuC1));
  1.4710 +  utilGzRead(gzFile, &gbDataHuC3, sizeof(gbDataHuC3));
  1.4711 +
  1.4712 +  if (version >= GBSAVE_GAME_VERSION_12)
  1.4713 +    {
  1.4714 +      utilGzRead(gzFile, pix, 4 * 257 * 226);
  1.4715 +    }
  1.4716 +  else
  1.4717 +    {
  1.4718 +      memset(pix, 0, 257 * 226 * sizeof(u32));
  1.4719 +      //		if(version < GBSAVE_GAME_VERSION_5)
  1.4720 +      //			utilGzRead(gzFile, pix, 256*224*sizeof(u16));
  1.4721 +    }
  1.4722 +
  1.4723 +  if (version < GBSAVE_GAME_VERSION_6)
  1.4724 +    {
  1.4725 +      utilGzRead(gzFile, gbPalette, 64 * sizeof(u16));
  1.4726 +    }
  1.4727 +  else
  1.4728 +    utilGzRead(gzFile, gbPalette, 128 * sizeof(u16));
  1.4729 +
  1.4730 +  // todo: remove
  1.4731 +  utilGzRead(gzFile, gbPalette, 128 * sizeof(u16));
  1.4732 +
  1.4733 +  if (version < GBSAVE_GAME_VERSION_10)
  1.4734 +    {
  1.4735 +      if (!gbCgbMode && !gbSgbMode)
  1.4736  	{
  1.4737 -		sprintf(tempBackupName, "gbatempsave%d.sav", tempStateID++);
  1.4738 -		gbWriteSaveState(tempBackupName);
  1.4739 +	  for (int i = 0; i < 8; i++)
  1.4740 +	    gbPalette[i] = systemGbPalette[gbPaletteOption * 8 + i];
  1.4741  	}
  1.4742 -
  1.4743 -	int version = utilReadInt(gzFile);
  1.4744 -
  1.4745 -	if (version > GBSAVE_GAME_VERSION || version < 0)
  1.4746 +    }
  1.4747 +
  1.4748 +  utilGzRead(gzFile, &gbMemory[0x8000], 0x8000);
  1.4749 +
  1.4750 +  if (gbRamSize && gbRam)
  1.4751 +    {
  1.4752 +      utilGzRead(gzFile, gbRam, gbRamSize);
  1.4753 +    }
  1.4754 +
  1.4755 +  gbMemoryMap[0x00] = &gbRom[0x0000];
  1.4756 +  gbMemoryMap[0x01] = &gbRom[0x1000];
  1.4757 +  gbMemoryMap[0x02] = &gbRom[0x2000];
  1.4758 +  gbMemoryMap[0x03] = &gbRom[0x3000];
  1.4759 +  gbMemoryMap[0x04] = &gbRom[0x4000];
  1.4760 +  gbMemoryMap[0x05] = &gbRom[0x5000];
  1.4761 +  gbMemoryMap[0x06] = &gbRom[0x6000];
  1.4762 +  gbMemoryMap[0x07] = &gbRom[0x7000];
  1.4763 +  gbMemoryMap[0x08] = &gbMemory[0x8000];
  1.4764 +  gbMemoryMap[0x09] = &gbMemory[0x9000];
  1.4765 +  gbMemoryMap[0x0a] = &gbMemory[0xa000];
  1.4766 +  gbMemoryMap[0x0b] = &gbMemory[0xb000];
  1.4767 +  gbMemoryMap[0x0c] = &gbMemory[0xc000];
  1.4768 +  gbMemoryMap[0x0d] = &gbMemory[0xd000];
  1.4769 +  gbMemoryMap[0x0e] = &gbMemory[0xe000];
  1.4770 +  gbMemoryMap[0x0f] = &gbMemory[0xf000];
  1.4771 +
  1.4772 +  type = gbRom[0x147];
  1.4773 +
  1.4774 +  switch (type)
  1.4775 +    {
  1.4776 +    case 0x00:
  1.4777 +    case 0x01:
  1.4778 +    case 0x02:
  1.4779 +    case 0x03:
  1.4780 +      // MBC 1
  1.4781 +      memoryUpdateMapMBC1();
  1.4782 +      break;
  1.4783 +    case 0x05:
  1.4784 +    case 0x06:
  1.4785 +      // MBC2
  1.4786 +      memoryUpdateMapMBC2();
  1.4787 +      break;
  1.4788 +    case 0x0f:
  1.4789 +    case 0x10:
  1.4790 +    case 0x11:
  1.4791 +    case 0x12:
  1.4792 +    case 0x13:
  1.4793 +      // MBC 3
  1.4794 +      memoryUpdateMapMBC3();
  1.4795 +      break;
  1.4796 +    case 0x19:
  1.4797 +    case 0x1a:
  1.4798 +    case 0x1b:
  1.4799 +      // MBC5
  1.4800 +      memoryUpdateMapMBC5();
  1.4801 +      break;
  1.4802 +    case 0x1c:
  1.4803 +    case 0x1d:
  1.4804 +    case 0x1e:
  1.4805 +      // MBC 5 Rumble
  1.4806 +      memoryUpdateMapMBC5();
  1.4807 +      break;
  1.4808 +    case 0x22:
  1.4809 +      // MBC 7
  1.4810 +      memoryUpdateMapMBC7();
  1.4811 +      break;
  1.4812 +    case 0xfe:
  1.4813 +      // HuC3
  1.4814 +      memoryUpdateMapHuC3();
  1.4815 +      break;
  1.4816 +    case 0xff:
  1.4817 +      // HuC1
  1.4818 +      memoryUpdateMapHuC1();
  1.4819 +      break;
  1.4820 +    }
  1.4821 +
  1.4822 +  if (gbCgbMode)
  1.4823 +    {
  1.4824 +      if (!gbVram)
  1.4825 +	gbVram = (u8 *)malloc(0x4000 + 4);
  1.4826 +      if (!gbWram)
  1.4827 +	gbWram = (u8 *)malloc(0x8000 + 4);
  1.4828 +      utilGzRead(gzFile, gbVram, 0x4000);
  1.4829 +      utilGzRead(gzFile, gbWram, 0x8000);
  1.4830 +
  1.4831 +      int value = register_SVBK;
  1.4832 +      if (value == 0)
  1.4833 +	value = 1;
  1.4834 +
  1.4835 +      gbMemoryMap[0x08] = &gbVram[register_VBK * 0x2000];
  1.4836 +      gbMemoryMap[0x09] = &gbVram[register_VBK * 0x2000 + 0x1000];
  1.4837 +      gbMemoryMap[0x0d] = &gbWram[value * 0x1000];
  1.4838 +    }
  1.4839 +  else
  1.4840 +    {
  1.4841 +      if (gbVram)
  1.4842  	{
  1.4843 -		systemMessage(MSG_UNSUPPORTED_VB_SGM,
  1.4844 -		              N_("Unsupported VisualBoy save game version %d"), version);
  1.4845 -		goto failedLoadGB;
  1.4846 +	  free(gbVram);
  1.4847 +	  gbVram = NULL;
  1.4848  	}
  1.4849 -
  1.4850 -	u8 romname[20];
  1.4851 -
  1.4852 -	utilGzRead(gzFile, romname, 15);
  1.4853 -
  1.4854 -	if (memcmp(&gbRom[0x134], romname, 15) != 0)
  1.4855 +      if (gbWram)
  1.4856  	{
  1.4857 -		systemMessage(MSG_CANNOT_LOAD_SGM_FOR,
  1.4858 -		              N_("Cannot load save game for %s. Playing %s"),
  1.4859 -		              romname, &gbRom[0x134]);
  1.4860 -		goto failedLoadGB;
  1.4861 +	  free(gbWram);
  1.4862 +	  gbWram = NULL;
  1.4863  	}
  1.4864 -
  1.4865 -	utilReadData(gzFile, gbSaveGameStruct);
  1.4866 -
  1.4867 -	if (version >= GBSAVE_GAME_VERSION_7)
  1.4868 +    }
  1.4869 +
  1.4870 +  gbSoundReadGame(version, gzFile);
  1.4871 +
  1.4872 +#if 0
  1.4873 +  if (gbBorderOn)
  1.4874 +    {
  1.4875 +      gbSgbRenderBorder();
  1.4876 +    }
  1.4877 +
  1.4878 +  systemRefreshScreen();
  1.4879 +#endif
  1.4880 +
  1.4881 +  if (version > GBSAVE_GAME_VERSION_1)
  1.4882 +    gbCheatsReadGame(gzFile, version);
  1.4883 +
  1.4884 +  systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED;
  1.4885 +
  1.4886 +  if (version >= GBSAVE_GAME_VERSION_11) // new to re-recording version:
  1.4887 +    {
  1.4888 +      extern int32 sensorX, sensorY; // from SDL.cpp
  1.4889 +      utilGzRead(gzFile, &sensorX, sizeof(sensorX));
  1.4890 +      utilGzRead(gzFile, &sensorY, sizeof(sensorY));
  1.4891 +      utilGzRead(gzFile, gbJoymask, 4 * sizeof(*gbJoymask)); // this has to be saved or old input will incorrectly get carried
  1.4892 +      // back on loading a snapshot!
  1.4893 +
  1.4894 +      bool8 movieSnapshot;
  1.4895 +      utilGzRead(gzFile, &movieSnapshot, sizeof(movieSnapshot));
  1.4896 +      if (VBAMovieActive() && !movieSnapshot)
  1.4897  	{
  1.4898 -		utilGzRead(gzFile, &IFF, 2);
  1.4899 +	  systemMessage(0, N_("Can't load a non-movie snapshot while a movie is active."));
  1.4900 +	  goto failedLoadGB;
  1.4901  	}
  1.4902  
  1.4903 -	if (gbSgbMode)
  1.4904 +      if (movieSnapshot) // even if a movie isn't active we still want to parse through this in case other stuff is added
  1.4905 +	// later on in the save format
  1.4906  	{
  1.4907 -		gbSgbReadGame(gzFile, version);
  1.4908 +	  uint32 movieInputDataSize = 0;
  1.4909 +	  utilGzRead(gzFile, &movieInputDataSize, sizeof(movieInputDataSize));
  1.4910 +	  uint8 *local_movie_data = new uint8 [movieInputDataSize];
  1.4911 +	  int	   readBytes		= utilGzRead(gzFile, local_movie_data, movieInputDataSize);
  1.4912 +	  if (readBytes != movieInputDataSize)
  1.4913 +	    {
  1.4914 +	      systemMessage(0, N_("Corrupt movie snapshot."));
  1.4915 +	      if (local_movie_data)
  1.4916 +		delete [] local_movie_data;
  1.4917 +	      goto failedLoadGB;
  1.4918 +	    }
  1.4919 +	  int code = VBAMovieUnfreeze(local_movie_data, movieInputDataSize);
  1.4920 +	  if (local_movie_data)
  1.4921 +	    delete [] local_movie_data;
  1.4922 +	  if (code != MOVIE_SUCCESS && VBAMovieActive())
  1.4923 +	    {
  1.4924 +	      char errStr [1024];
  1.4925 +	      strcpy(errStr, "Failed to load movie snapshot");
  1.4926 +	      switch (code)
  1.4927 +		{
  1.4928 +		case MOVIE_NOT_FROM_THIS_MOVIE:
  1.4929 +		  strcat(errStr, ";\nSnapshot not from this movie"); break;
  1.4930 +		case MOVIE_NOT_FROM_A_MOVIE:
  1.4931 +		  strcat(errStr, ";\nNot a movie snapshot"); break;                    // shouldn't get here...
  1.4932 +		case MOVIE_SNAPSHOT_INCONSISTENT:
  1.4933 +		  strcat(errStr, ";\nSnapshot inconsistent with movie"); break;
  1.4934 +		case MOVIE_WRONG_FORMAT:
  1.4935 +		  strcat(errStr, ";\nWrong format"); break;
  1.4936 +		}
  1.4937 +	      strcat(errStr, ".");
  1.4938 +	      systemMessage(0, N_(errStr));
  1.4939 +	      goto failedLoadGB;
  1.4940 +	    }
  1.4941  	}
  1.4942 -	else
  1.4943 -	{
  1.4944 -		gbSgbMask = 0; // loading a game at the wrong time causes no display
  1.4945 -	}
  1.4946 -
  1.4947 -	utilGzRead(gzFile, &gbDataMBC1, sizeof(gbDataMBC1));
  1.4948 -	utilGzRead(gzFile, &gbDataMBC2, sizeof(gbDataMBC2));
  1.4949 -	if (version < GBSAVE_GAME_VERSION_4)
  1.4950 -		// prior to version 4, there was no adjustment for the time the game
  1.4951 -		// was last played, so we have less to read. This needs update if the
  1.4952 -		// structure changes again.
  1.4953 -		utilGzRead(gzFile, &gbDataMBC3, sizeof(int32) * 10);
  1.4954 -	else
  1.4955 -	{
  1.4956 -		//assert(sizeof(time_t) == 4);
  1.4957 -		utilGzRead(gzFile, &gbDataMBC3, sizeof(gbDataMBC3));
  1.4958 -	}
  1.4959 -	utilGzRead(gzFile, &gbDataMBC5, sizeof(gbDataMBC5));
  1.4960 -	utilGzRead(gzFile, &gbDataHuC1, sizeof(gbDataHuC1));
  1.4961 -	utilGzRead(gzFile, &gbDataHuC3, sizeof(gbDataHuC3));
  1.4962 -
  1.4963 -	if (version >= GBSAVE_GAME_VERSION_12)
  1.4964 -	{
  1.4965 -		utilGzRead(gzFile, pix, 4 * 257 * 226);
  1.4966 -	}
  1.4967 -	else
  1.4968 -	{
  1.4969 -		memset(pix, 0, 257 * 226 * sizeof(u32));
  1.4970 -//		if(version < GBSAVE_GAME_VERSION_5)
  1.4971 -//			utilGzRead(gzFile, pix, 256*224*sizeof(u16));
  1.4972 -	}
  1.4973 -
  1.4974 -	if (version < GBSAVE_GAME_VERSION_6)
  1.4975 -	{
  1.4976 -		utilGzRead(gzFile, gbPalette, 64 * sizeof(u16));
  1.4977 -	}
  1.4978 -	else
  1.4979 -		utilGzRead(gzFile, gbPalette, 128 * sizeof(u16));
  1.4980 -
  1.4981 -	// todo: remove
  1.4982 -	utilGzRead(gzFile, gbPalette, 128 * sizeof(u16));
  1.4983 -
  1.4984 -	if (version < GBSAVE_GAME_VERSION_10)
  1.4985 -	{
  1.4986 -		if (!gbCgbMode && !gbSgbMode)
  1.4987 -		{
  1.4988 -			for (int i = 0; i < 8; i++)
  1.4989 -				gbPalette[i] = systemGbPalette[gbPaletteOption * 8 + i];
  1.4990 -		}
  1.4991 -	}
  1.4992 -
  1.4993 -	utilGzRead(gzFile, &gbMemory[0x8000], 0x8000);
  1.4994 -
  1.4995 -	if (gbRamSize && gbRam)
  1.4996 -	{
  1.4997 -		utilGzRead(gzFile, gbRam, gbRamSize);
  1.4998 -	}
  1.4999 -
  1.5000 -	gbMemoryMap[0x00] = &gbRom[0x0000];
  1.5001 -	gbMemoryMap[0x01] = &gbRom[0x1000];
  1.5002 -	gbMemoryMap[0x02] = &gbRom[0x2000];
  1.5003 -	gbMemoryMap[0x03] = &gbRom[0x3000];
  1.5004 -	gbMemoryMap[0x04] = &gbRom[0x4000];
  1.5005 -	gbMemoryMap[0x05] = &gbRom[0x5000];
  1.5006 -	gbMemoryMap[0x06] = &gbRom[0x6000];
  1.5007 -	gbMemoryMap[0x07] = &gbRom[0x7000];
  1.5008 -	gbMemoryMap[0x08] = &gbMemory[0x8000];
  1.5009 -	gbMemoryMap[0x09] = &gbMemory[0x9000];
  1.5010 -	gbMemoryMap[0x0a] = &gbMemory[0xa000];
  1.5011 -	gbMemoryMap[0x0b] = &gbMemory[0xb000];
  1.5012 -	gbMemoryMap[0x0c] = &gbMemory[0xc000];
  1.5013 -	gbMemoryMap[0x0d] = &gbMemory[0xd000];
  1.5014 -	gbMemoryMap[0x0e] = &gbMemory[0xe000];
  1.5015 -	gbMemoryMap[0x0f] = &gbMemory[0xf000];
  1.5016 -
  1.5017 -	type = gbRom[0x147];
  1.5018 -
  1.5019 -	switch (type)
  1.5020 -	{
  1.5021 -	case 0x00:
  1.5022 -	case 0x01:
  1.5023 -	case 0x02:
  1.5024 -	case 0x03:
  1.5025 -		// MBC 1
  1.5026 -		memoryUpdateMapMBC1();
  1.5027 -		break;
  1.5028 -	case 0x05:
  1.5029 -	case 0x06:
  1.5030 -		// MBC2
  1.5031 -		memoryUpdateMapMBC2();
  1.5032 -		break;
  1.5033 -	case 0x0f:
  1.5034 -	case 0x10:
  1.5035 -	case 0x11:
  1.5036 -	case 0x12:
  1.5037 -	case 0x13:
  1.5038 -		// MBC 3
  1.5039 -		memoryUpdateMapMBC3();
  1.5040 -		break;
  1.5041 -	case 0x19:
  1.5042 -	case 0x1a:
  1.5043 -	case 0x1b:
  1.5044 -		// MBC5
  1.5045 -		memoryUpdateMapMBC5();
  1.5046 -		break;
  1.5047 -	case 0x1c:
  1.5048 -	case 0x1d:
  1.5049 -	case 0x1e:
  1.5050 -		// MBC 5 Rumble
  1.5051 -		memoryUpdateMapMBC5();
  1.5052 -		break;
  1.5053 -	case 0x22:
  1.5054 -		// MBC 7
  1.5055 -		memoryUpdateMapMBC7();
  1.5056 -		break;
  1.5057 -	case 0xfe:
  1.5058 -		// HuC3
  1.5059 -		memoryUpdateMapHuC3();
  1.5060 -		break;
  1.5061 -	case 0xff:
  1.5062 -		// HuC1
  1.5063 -		memoryUpdateMapHuC1();
  1.5064 -		break;
  1.5065 -	}
  1.5066 -
  1.5067 -	if (gbCgbMode)
  1.5068 -	{
  1.5069 -		if (!gbVram)
  1.5070 -			gbVram = (u8 *)malloc(0x4000 + 4);
  1.5071 -		if (!gbWram)
  1.5072 -			gbWram = (u8 *)malloc(0x8000 + 4);
  1.5073 -		utilGzRead(gzFile, gbVram, 0x4000);
  1.5074 -		utilGzRead(gzFile, gbWram, 0x8000);
  1.5075 -
  1.5076 -		int value = register_SVBK;
  1.5077 -		if (value == 0)
  1.5078 -			value = 1;
  1.5079 -
  1.5080 -		gbMemoryMap[0x08] = &gbVram[register_VBK * 0x2000];
  1.5081 -		gbMemoryMap[0x09] = &gbVram[register_VBK * 0x2000 + 0x1000];
  1.5082 -		gbMemoryMap[0x0d] = &gbWram[value * 0x1000];
  1.5083 -	}
  1.5084 -	else
  1.5085 -	{
  1.5086 -		if (gbVram)
  1.5087 -		{
  1.5088 -			free(gbVram);
  1.5089 -			gbVram = NULL;
  1.5090 -		}
  1.5091 -		if (gbWram)
  1.5092 -		{
  1.5093 -			free(gbWram);
  1.5094 -			gbWram = NULL;
  1.5095 -		}
  1.5096 -	}
  1.5097 -
  1.5098 -	gbSoundReadGame(version, gzFile);
  1.5099 -
  1.5100 -#if 0
  1.5101 -	if (gbBorderOn)
  1.5102 -	{
  1.5103 -		gbSgbRenderBorder();
  1.5104 -	}
  1.5105 -
  1.5106 -	systemRefreshScreen();
  1.5107 -#endif
  1.5108 -
  1.5109 -	if (version > GBSAVE_GAME_VERSION_1)
  1.5110 -		gbCheatsReadGame(gzFile, version);
  1.5111 -
  1.5112 -	systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED;
  1.5113 -
  1.5114 -	if (version >= GBSAVE_GAME_VERSION_11) // new to re-recording version:
  1.5115 -	{
  1.5116 -		extern int32 sensorX, sensorY; // from SDL.cpp
  1.5117 -		utilGzRead(gzFile, &sensorX, sizeof(sensorX));
  1.5118 -		utilGzRead(gzFile, &sensorY, sizeof(sensorY));
  1.5119 -		utilGzRead(gzFile, gbJoymask, 4 * sizeof(*gbJoymask)); // this has to be saved or old input will incorrectly get carried
  1.5120 -		                                                       // back on loading a snapshot!
  1.5121 -
  1.5122 -		bool8 movieSnapshot;
  1.5123 -		utilGzRead(gzFile, &movieSnapshot, sizeof(movieSnapshot));
  1.5124 -		if (VBAMovieActive() && !movieSnapshot)
  1.5125 -		{
  1.5126 -			systemMessage(0, N_("Can't load a non-movie snapshot while a movie is active."));
  1.5127 -			goto failedLoadGB;
  1.5128 -		}
  1.5129 -
  1.5130 -		if (movieSnapshot) // even if a movie isn't active we still want to parse through this in case other stuff is added
  1.5131 -		                   // later on in the save format
  1.5132 -		{
  1.5133 -			uint32 movieInputDataSize = 0;
  1.5134 -			utilGzRead(gzFile, &movieInputDataSize, sizeof(movieInputDataSize));
  1.5135 -			uint8 *local_movie_data = new uint8 [movieInputDataSize];
  1.5136 -			int	   readBytes		= utilGzRead(gzFile, local_movie_data, movieInputDataSize);
  1.5137 -			if (readBytes != movieInputDataSize)
  1.5138 -			{
  1.5139 -				systemMessage(0, N_("Corrupt movie snapshot."));
  1.5140 -				if (local_movie_data)
  1.5141 -					delete [] local_movie_data;
  1.5142 -				goto failedLoadGB;
  1.5143 -			}
  1.5144 -			int code = VBAMovieUnfreeze(local_movie_data, movieInputDataSize);
  1.5145 -			if (local_movie_data)
  1.5146 -				delete [] local_movie_data;
  1.5147 -			if (code != MOVIE_SUCCESS && VBAMovieActive())
  1.5148 -			{
  1.5149 -				char errStr [1024];
  1.5150 -				strcpy(errStr, "Failed to load movie snapshot");
  1.5151 -				switch (code)
  1.5152 -				{
  1.5153 -				case MOVIE_NOT_FROM_THIS_MOVIE:
  1.5154 -					strcat(errStr, ";\nSnapshot not from this movie"); break;
  1.5155 -				case MOVIE_NOT_FROM_A_MOVIE:
  1.5156 -					strcat(errStr, ";\nNot a movie snapshot"); break;                    // shouldn't get here...
  1.5157 -				case MOVIE_SNAPSHOT_INCONSISTENT:
  1.5158 -					strcat(errStr, ";\nSnapshot inconsistent with movie"); break;
  1.5159 -				case MOVIE_WRONG_FORMAT:
  1.5160 -					strcat(errStr, ";\nWrong format"); break;
  1.5161 -				}
  1.5162 -				strcat(errStr, ".");
  1.5163 -				systemMessage(0, N_(errStr));
  1.5164 -				goto failedLoadGB;
  1.5165 -			}
  1.5166 -		}
  1.5167 -		utilGzRead(gzFile, &GBSystemCounters.frameCount, sizeof(GBSystemCounters.frameCount));
  1.5168 -	}
  1.5169 -
  1.5170 -	if (version >= GBSAVE_GAME_VERSION_13)   // new to rerecording 19.4 wip (svn r22+):
  1.5171 -	{
  1.5172 -		utilGzRead(gzFile, &GBSystemCounters.lagCount, sizeof(GBSystemCounters.lagCount));
  1.5173 -		utilGzRead(gzFile, &GBSystemCounters.lagged, sizeof(GBSystemCounters.lagged));
  1.5174 -		utilGzRead(gzFile, &GBSystemCounters.laggedLast, sizeof(GBSystemCounters.laggedLast));
  1.5175 -	}
  1.5176 -
  1.5177 -	if (backupSafe)
  1.5178 -	{
  1.5179 -		remove(tempBackupName);
  1.5180 -		tempFailCount = 0;
  1.5181 -	}
  1.5182 -
  1.5183 -	for (int i = 0; i < 4; ++i)
  1.5184 -		systemSetJoypad(i, gbJoymask[i] & 0xFFFF);
  1.5185 -
  1.5186 -	// FIXME: horrible kludge
  1.5187 -	memcpy(s_gbJoymask, gbJoymask, sizeof(gbJoymask));
  1.5188 -
  1.5189 -	VBAUpdateButtonPressDisplay();
  1.5190 -	VBAUpdateFrameCountDisplay();
  1.5191 -	systemRefreshScreen();
  1.5192 -	return true;
  1.5193 -
  1.5194 -failedLoadGB:
  1.5195 -	if (backupSafe)
  1.5196 -	{
  1.5197 -		tempFailCount++;
  1.5198 -		if (tempFailCount < 3) // fail no more than 2 times in a row
  1.5199 -			gbReadSaveState(tempBackupName);
  1.5200 -		remove(tempBackupName);
  1.5201 -	}
  1.5202 -	return false;
  1.5203 +      utilGzRead(gzFile, &GBSystemCounters.frameCount, sizeof(GBSystemCounters.frameCount));
  1.5204 +    }
  1.5205 +
  1.5206 +  if (version >= GBSAVE_GAME_VERSION_13)   // new to rerecording 19.4 wip (svn r22+):
  1.5207 +    {
  1.5208 +      utilGzRead(gzFile, &GBSystemCounters.lagCount, sizeof(GBSystemCounters.lagCount));
  1.5209 +      utilGzRead(gzFile, &GBSystemCounters.lagged, sizeof(GBSystemCounters.lagged));
  1.5210 +      utilGzRead(gzFile, &GBSystemCounters.laggedLast, sizeof(GBSystemCounters.laggedLast));
  1.5211 +    }
  1.5212 +
  1.5213 +  if (backupSafe)
  1.5214 +    {
  1.5215 +      remove(tempBackupName);
  1.5216 +      tempFailCount = 0;
  1.5217 +    }
  1.5218 +
  1.5219 +  for (int i = 0; i < 4; ++i)
  1.5220 +    systemSetJoypad(i, gbJoymask[i] & 0xFFFF);
  1.5221 +
  1.5222 +  // FIXME: horrible kludge
  1.5223 +  memcpy(s_gbJoymask, gbJoymask, sizeof(gbJoymask));
  1.5224 +
  1.5225 +  VBAUpdateButtonPressDisplay();
  1.5226 +  VBAUpdateFrameCountDisplay();
  1.5227 +  systemRefreshScreen();
  1.5228 +  return true;
  1.5229 +
  1.5230 + failedLoadGB:
  1.5231 +  if (backupSafe)
  1.5232 +    {
  1.5233 +      tempFailCount++;
  1.5234 +      if (tempFailCount < 3) // fail no more than 2 times in a row
  1.5235 +	gbReadSaveState(tempBackupName);
  1.5236 +      remove(tempBackupName);
  1.5237 +    }
  1.5238 +  return false;
  1.5239  }
  1.5240  
  1.5241  bool gbReadMemSaveState(char *memory, int available)
  1.5242  {
  1.5243 -	gzFile gzFile = utilMemGzOpen(memory, available, "r");
  1.5244 -
  1.5245 -	backupSafe = false;
  1.5246 -	bool res = gbReadSaveStateFromStream(gzFile);
  1.5247 -	backupSafe = true;
  1.5248 -
  1.5249 -	utilGzClose(gzFile);
  1.5250 -
  1.5251 -	return res;
  1.5252 +  gzFile gzFile = utilMemGzOpen(memory, available, "r");
  1.5253 +
  1.5254 +  backupSafe = false;
  1.5255 +  bool res = gbReadSaveStateFromStream(gzFile);
  1.5256 +  backupSafe = true;
  1.5257 +
  1.5258 +  utilGzClose(gzFile);
  1.5259 +
  1.5260 +  return res;
  1.5261  }
  1.5262  
  1.5263  bool gbReadSaveState(const char *name)
  1.5264  {
  1.5265 -	gzFile gzFile = utilGzOpen(name, "rb");
  1.5266 -
  1.5267 -	if (gzFile == NULL)
  1.5268 -	{
  1.5269 -		return false;
  1.5270 -	}
  1.5271 -
  1.5272 -	bool res = gbReadSaveStateFromStream(gzFile);
  1.5273 -
  1.5274 -	utilGzClose(gzFile);
  1.5275 -
  1.5276 -	return res;
  1.5277 +  gzFile gzFile = utilGzOpen(name, "rb");
  1.5278 +
  1.5279 +  if (gzFile == NULL)
  1.5280 +    {
  1.5281 +      return false;
  1.5282 +    }
  1.5283 +
  1.5284 +  bool res = gbReadSaveStateFromStream(gzFile);
  1.5285 +
  1.5286 +  utilGzClose(gzFile);
  1.5287 +
  1.5288 +  return res;
  1.5289  }
  1.5290  
  1.5291  bool gbWritePNGFile(const char *fileName)
  1.5292  {
  1.5293 -	if (gbBorderOn)
  1.5294 -		return utilWritePNGFile(fileName, 256, 224, pix);
  1.5295 -	return utilWritePNGFile(fileName, 160, 144, pix);
  1.5296 +  if (gbBorderOn)
  1.5297 +    return utilWritePNGFile(fileName, 256, 224, pix);
  1.5298 +  return utilWritePNGFile(fileName, 160, 144, pix);
  1.5299  }
  1.5300  
  1.5301  bool gbWriteBMPFile(const char *fileName)
  1.5302  {
  1.5303 -	if (gbBorderOn)
  1.5304 -		return utilWriteBMPFile(fileName, 256, 224, pix);
  1.5305 -	return utilWriteBMPFile(fileName, 160, 144, pix);
  1.5306 +  if (gbBorderOn)
  1.5307 +    return utilWriteBMPFile(fileName, 256, 224, pix);
  1.5308 +  return utilWriteBMPFile(fileName, 160, 144, pix);
  1.5309  }
  1.5310  
  1.5311  void gbCleanUp()
  1.5312  {
  1.5313 -	newFrame	  = true;
  1.5314 -
  1.5315 -	GBSystemCounters.frameCount = 0;
  1.5316 -	GBSystemCounters.lagCount	= 0;
  1.5317 -	GBSystemCounters.extraCount = 0;
  1.5318 -	GBSystemCounters.lagged		= true;
  1.5319 -	GBSystemCounters.laggedLast = true;
  1.5320 -
  1.5321 -	if (gbRam != NULL)
  1.5322 -	{
  1.5323 -		free(gbRam);
  1.5324 -		gbRam = NULL;
  1.5325 -	}
  1.5326 -
  1.5327 -	if (gbRom != NULL)
  1.5328 -	{
  1.5329 -		free(gbRom);
  1.5330 -		gbRom = NULL;
  1.5331 -	}
  1.5332 -
  1.5333 -	if (gbMemory != NULL)
  1.5334 -	{
  1.5335 -		free(gbMemory);
  1.5336 -		gbMemory = NULL;
  1.5337 -	}
  1.5338 -
  1.5339 -	if (gbLineBuffer != NULL)
  1.5340 -	{
  1.5341 -		free(gbLineBuffer);
  1.5342 -		gbLineBuffer = NULL;
  1.5343 -	}
  1.5344 -
  1.5345 -	if (origPix != NULL)
  1.5346 -	{
  1.5347 -		free(origPix);
  1.5348 -		origPix = NULL;
  1.5349 -	}
  1.5350 -	pix = NULL;
  1.5351 -
  1.5352 -	gbSgbShutdown();
  1.5353 -
  1.5354 -	if (gbVram != NULL)
  1.5355 -	{
  1.5356 -		free(gbVram);
  1.5357 -		gbVram = NULL;
  1.5358 -	}
  1.5359 -
  1.5360 -	if (gbWram != NULL)
  1.5361 -	{
  1.5362 -		free(gbWram);
  1.5363 -		gbWram = NULL;
  1.5364 -	}
  1.5365 -
  1.5366 -	systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED;
  1.5367 -
  1.5368 -	memset(gbJoymask, 0, sizeof(gbJoymask));
  1.5369 -	// FIXME: horrible kludge
  1.5370 -	memset(s_gbJoymask, 0, sizeof(s_gbJoymask));
  1.5371 -
  1.5372 -	systemClearJoypads();
  1.5373 -	systemResetSensor();
  1.5374 -
  1.5375 -//	gbLastTime = gbFrameCount = 0;
  1.5376 -	systemRefreshScreen();
  1.5377 +  newFrame	  = true;
  1.5378 +
  1.5379 +  GBSystemCounters.frameCount = 0;
  1.5380 +  GBSystemCounters.lagCount	= 0;
  1.5381 +  GBSystemCounters.extraCount = 0;
  1.5382 +  GBSystemCounters.lagged		= true;
  1.5383 +  GBSystemCounters.laggedLast = true;
  1.5384 +
  1.5385 +  if (gbRam != NULL)
  1.5386 +    {
  1.5387 +      free(gbRam);
  1.5388 +      gbRam = NULL;
  1.5389 +    }
  1.5390 +
  1.5391 +  if (gbRom != NULL)
  1.5392 +    {
  1.5393 +      free(gbRom);
  1.5394 +      gbRom = NULL;
  1.5395 +    }
  1.5396 +
  1.5397 +  if (gbMemory != NULL)
  1.5398 +    {
  1.5399 +      free(gbMemory);
  1.5400 +      gbMemory = NULL;
  1.5401 +    }
  1.5402 +
  1.5403 +  if (gbLineBuffer != NULL)
  1.5404 +    {
  1.5405 +      free(gbLineBuffer);
  1.5406 +      gbLineBuffer = NULL;
  1.5407 +    }
  1.5408 +
  1.5409 +  if (origPix != NULL)
  1.5410 +    {
  1.5411 +      free(origPix);
  1.5412 +      origPix = NULL;
  1.5413 +    }
  1.5414 +  pix = NULL;
  1.5415 +
  1.5416 +  gbSgbShutdown();
  1.5417 +
  1.5418 +  if (gbVram != NULL)
  1.5419 +    {
  1.5420 +      free(gbVram);
  1.5421 +      gbVram = NULL;
  1.5422 +    }
  1.5423 +
  1.5424 +  if (gbWram != NULL)
  1.5425 +    {
  1.5426 +      free(gbWram);
  1.5427 +      gbWram = NULL;
  1.5428 +    }
  1.5429 +
  1.5430 +  systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED;
  1.5431 +
  1.5432 +  memset(gbJoymask, 0, sizeof(gbJoymask));
  1.5433 +  // FIXME: horrible kludge
  1.5434 +  memset(s_gbJoymask, 0, sizeof(s_gbJoymask));
  1.5435 +
  1.5436 +  systemClearJoypads();
  1.5437 +  systemResetSensor();
  1.5438 +
  1.5439 +  //	gbLastTime = gbFrameCount = 0;
  1.5440 +  systemRefreshScreen();
  1.5441  }
  1.5442  
  1.5443  bool gbLoadRom(const char *szFile)
  1.5444  {
  1.5445 -	int size = 0;
  1.5446 -
  1.5447 -	if (gbRom != NULL)
  1.5448 -	{
  1.5449 -		gbCleanUp();
  1.5450 -	}
  1.5451 -
  1.5452 -	systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED;
  1.5453 -
  1.5454 -	gbRom = utilLoad(szFile,
  1.5455 -	                 utilIsGBImage,
  1.5456 -	                 NULL,
  1.5457 -	                 size);
  1.5458 -	if (!gbRom)
  1.5459 -		return false;
  1.5460 -
  1.5461 -	gbRomSize = size;
  1.5462 -
  1.5463 -	return gbUpdateSizes();
  1.5464 +  int size = 0;
  1.5465 +
  1.5466 +  if (gbRom != NULL)
  1.5467 +    {
  1.5468 +      gbCleanUp();
  1.5469 +    }
  1.5470 +
  1.5471 +  systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED;
  1.5472 +
  1.5473 +  gbRom = utilLoad(szFile,
  1.5474 +		   utilIsGBImage,
  1.5475 +		   NULL,
  1.5476 +		   size);
  1.5477 +  if (!gbRom)
  1.5478 +    return false;
  1.5479 +
  1.5480 +  gbRomSize = size;
  1.5481 +
  1.5482 +  return gbUpdateSizes();
  1.5483  }
  1.5484  
  1.5485  bool gbUpdateSizes()
  1.5486  {
  1.5487 -	if (gbRom[0x148] > 8)
  1.5488 -	{
  1.5489 -		systemMessage(MSG_UNSUPPORTED_ROM_SIZE,
  1.5490 -		              N_("Unsupported rom size %02x"), gbRom[0x148]);
  1.5491 -		return false;
  1.5492 -	}
  1.5493 -
  1.5494 -	if (gbRomSize < gbRomSizes[gbRom[0x148]])
  1.5495 -	{
  1.5496 -		gbRom = (u8 *)realloc(gbRom, gbRomSizes[gbRom[0x148]]);
  1.5497 -	}
  1.5498 -	gbRomSize	  = gbRomSizes[gbRom[0x148]];
  1.5499 -	gbRomSizeMask = gbRomSizesMasks[gbRom[0x148]];
  1.5500 -
  1.5501 -	if (gbRom[0x149] > 5)
  1.5502 -	{
  1.5503 -		systemMessage(MSG_UNSUPPORTED_RAM_SIZE,
  1.5504 -		              N_("Unsupported ram size %02x"), gbRom[0x149]);
  1.5505 -		return false;
  1.5506 -	}
  1.5507 -
  1.5508 -	gbRamSize	  = gbRamSizes[gbRom[0x149]];
  1.5509 -	gbRamSizeMask = gbRamSizesMasks[gbRom[0x149]];
  1.5510 -
  1.5511 -	if (gbRamSize)
  1.5512 -	{
  1.5513 -		gbRam = (u8 *)malloc(gbRamSize + 4);
  1.5514 -		memset(gbRam, 0xFF, gbRamSize + 4);
  1.5515 -	}
  1.5516 -
  1.5517 -	int type = gbRom[0x147];
  1.5518 -
  1.5519 -	mapperReadRAM = NULL;
  1.5520 -
  1.5521 -	switch (type)
  1.5522 -	{
  1.5523 -	case 0x00:
  1.5524 -	case 0x01:
  1.5525 -	case 0x02:
  1.5526 -	case 0x03:
  1.5527 -		// MBC 1
  1.5528 -		mapper	  = mapperMBC1ROM;
  1.5529 -		mapperRAM = mapperMBC1RAM;
  1.5530 -		break;
  1.5531 -	case 0x05:
  1.5532 -	case 0x06:
  1.5533 -		// MBC2
  1.5534 -		mapper		  = mapperMBC2ROM;
  1.5535 -		mapperRAM	  = mapperMBC2RAM;
  1.5536 -		gbRamSize	  = 0x200;
  1.5537 -		gbRamSizeMask = 0x1ff;
  1.5538 -		break;
  1.5539 -	case 0x0f:
  1.5540 -	case 0x10:
  1.5541 -	case 0x11:
  1.5542 -	case 0x12:
  1.5543 -	case 0x13:
  1.5544 -		// MBC 3
  1.5545 -		mapper		  = mapperMBC3ROM;
  1.5546 -		mapperRAM	  = mapperMBC3RAM;
  1.5547 -		mapperReadRAM = mapperMBC3ReadRAM;
  1.5548 -		break;
  1.5549 -	case 0x19:
  1.5550 -	case 0x1a:
  1.5551 -	case 0x1b:
  1.5552 -		// MBC5
  1.5553 -		mapper	  = mapperMBC5ROM;
  1.5554 -		mapperRAM = mapperMBC5RAM;
  1.5555 -		break;
  1.5556 -	case 0x1c:
  1.5557 -	case 0x1d:
  1.5558 -	case 0x1e:
  1.5559 -		// MBC 5 Rumble
  1.5560 -		mapper	  = mapperMBC5ROM;
  1.5561 -		mapperRAM = mapperMBC5RAM;
  1.5562 -		break;
  1.5563 -	case 0x22:
  1.5564 -		// MBC 7
  1.5565 -		mapper		  = mapperMBC7ROM;
  1.5566 -		mapperRAM	  = mapperMBC7RAM;
  1.5567 -		mapperReadRAM = mapperMBC7ReadRAM;
  1.5568 -		break;
  1.5569 -	case 0xfe:
  1.5570 -		// HuC3
  1.5571 -		mapper		  = mapperHuC3ROM;
  1.5572 -		mapperRAM	  = mapperHuC3RAM;
  1.5573 -		mapperReadRAM = mapperHuC3ReadRAM;
  1.5574 -		break;
  1.5575 -	case 0xff:
  1.5576 -		// HuC1
  1.5577 -		mapper	  = mapperHuC1ROM;
  1.5578 -		mapperRAM = mapperHuC1RAM;
  1.5579 -		break;
  1.5580 -	default:
  1.5581 -		systemMessage(MSG_UNKNOWN_CARTRIDGE_TYPE,
  1.5582 -		              N_("Unknown cartridge type %02x"), type);
  1.5583 -		return false;
  1.5584 -	}
  1.5585 -
  1.5586 -	switch (type)
  1.5587 -	{
  1.5588 -	case 0x03:
  1.5589 -	case 0x06:
  1.5590 -	case 0x0f:
  1.5591 -	case 0x10:
  1.5592 -	case 0x13:
  1.5593 -	case 0x1b:
  1.5594 -	case 0x1d:
  1.5595 -	case 0x1e:
  1.5596 -	case 0x22:
  1.5597 -	case 0xff:
  1.5598 -		gbBattery = 1;
  1.5599 -		break;
  1.5600 -	}
  1.5601 -
  1.5602 -	gbInit();
  1.5603 -	gbReset();
  1.5604 -
  1.5605 -	return true;
  1.5606 +  if (gbRom[0x148] > 8)
  1.5607 +    {
  1.5608 +      systemMessage(MSG_UNSUPPORTED_ROM_SIZE,
  1.5609 +		    N_("Unsupported rom size %02x"), gbRom[0x148]);
  1.5610 +      return false;
  1.5611 +    }
  1.5612 +
  1.5613 +  if (gbRomSize < gbRomSizes[gbRom[0x148]])
  1.5614 +    {
  1.5615 +      gbRom = (u8 *)realloc(gbRom, gbRomSizes[gbRom[0x148]]);
  1.5616 +    }
  1.5617 +  gbRomSize	  = gbRomSizes[gbRom[0x148]];
  1.5618 +  gbRomSizeMask = gbRomSizesMasks[gbRom[0x148]];
  1.5619 +
  1.5620 +  if (gbRom[0x149] > 5)
  1.5621 +    {
  1.5622 +      systemMessage(MSG_UNSUPPORTED_RAM_SIZE,
  1.5623 +		    N_("Unsupported ram size %02x"), gbRom[0x149]);
  1.5624 +      return false;
  1.5625 +    }
  1.5626 +
  1.5627 +  gbRamSize	  = gbRamSizes[gbRom[0x149]];
  1.5628 +  gbRamSizeMask = gbRamSizesMasks[gbRom[0x149]];
  1.5629 +
  1.5630 +  if (gbRamSize)
  1.5631 +    {
  1.5632 +      gbRam = (u8 *)malloc(gbRamSize + 4);
  1.5633 +      memset(gbRam, 0xFF, gbRamSize + 4);
  1.5634 +    }
  1.5635 +
  1.5636 +  int type = gbRom[0x147];
  1.5637 +
  1.5638 +  mapperReadRAM = NULL;
  1.5639 +
  1.5640 +  switch (type)
  1.5641 +    {
  1.5642 +    case 0x00:
  1.5643 +    case 0x01:
  1.5644 +    case 0x02:
  1.5645 +    case 0x03:
  1.5646 +      // MBC 1
  1.5647 +      mapper	  = mapperMBC1ROM;
  1.5648 +      mapperRAM = mapperMBC1RAM;
  1.5649 +      break;
  1.5650 +    case 0x05:
  1.5651 +    case 0x06:
  1.5652 +      // MBC2
  1.5653 +      mapper		  = mapperMBC2ROM;
  1.5654 +      mapperRAM	  = mapperMBC2RAM;
  1.5655 +      gbRamSize	  = 0x200;
  1.5656 +      gbRamSizeMask = 0x1ff;
  1.5657 +      break;
  1.5658 +    case 0x0f:
  1.5659 +    case 0x10:
  1.5660 +    case 0x11:
  1.5661 +    case 0x12:
  1.5662 +    case 0x13:
  1.5663 +      // MBC 3
  1.5664 +      mapper		  = mapperMBC3ROM;
  1.5665 +      mapperRAM	  = mapperMBC3RAM;
  1.5666 +      mapperReadRAM = mapperMBC3ReadRAM;
  1.5667 +      break;
  1.5668 +    case 0x19:
  1.5669 +    case 0x1a:
  1.5670 +    case 0x1b:
  1.5671 +      // MBC5
  1.5672 +      mapper	  = mapperMBC5ROM;
  1.5673 +      mapperRAM = mapperMBC5RAM;
  1.5674 +      break;
  1.5675 +    case 0x1c:
  1.5676 +    case 0x1d:
  1.5677 +    case 0x1e:
  1.5678 +      // MBC 5 Rumble
  1.5679 +      mapper	  = mapperMBC5ROM;
  1.5680 +      mapperRAM = mapperMBC5RAM;
  1.5681 +      break;
  1.5682 +    case 0x22:
  1.5683 +      // MBC 7
  1.5684 +      mapper		  = mapperMBC7ROM;
  1.5685 +      mapperRAM	  = mapperMBC7RAM;
  1.5686 +      mapperReadRAM = mapperMBC7ReadRAM;
  1.5687 +      break;
  1.5688 +    case 0xfe:
  1.5689 +      // HuC3
  1.5690 +      mapper		  = mapperHuC3ROM;
  1.5691 +      mapperRAM	  = mapperHuC3RAM;
  1.5692 +      mapperReadRAM = mapperHuC3ReadRAM;
  1.5693 +      break;
  1.5694 +    case 0xff:
  1.5695 +      // HuC1
  1.5696 +      mapper	  = mapperHuC1ROM;
  1.5697 +      mapperRAM = mapperHuC1RAM;
  1.5698 +      break;
  1.5699 +    default:
  1.5700 +      systemMessage(MSG_UNKNOWN_CARTRIDGE_TYPE,
  1.5701 +		    N_("Unknown cartridge type %02x"), type);
  1.5702 +      return false;
  1.5703 +    }
  1.5704 +
  1.5705 +  switch (type)
  1.5706 +    {
  1.5707 +    case 0x03:
  1.5708 +    case 0x06:
  1.5709 +    case 0x0f:
  1.5710 +    case 0x10:
  1.5711 +    case 0x13:
  1.5712 +    case 0x1b:
  1.5713 +    case 0x1d:
  1.5714 +    case 0x1e:
  1.5715 +    case 0x22:
  1.5716 +    case 0xff:
  1.5717 +      gbBattery = 1;
  1.5718 +      break;
  1.5719 +    }
  1.5720 +
  1.5721 +  gbInit();
  1.5722 +  gbReset();
  1.5723 +
  1.5724 +  return true;
  1.5725  }
  1.5726  
  1.5727  void gbEmulate(int ticksToStop)
  1.5728  {
  1.5729 -	gbRegister tempRegister;
  1.5730 -	u8		   tempValue;
  1.5731 -	s8		   offset;
  1.5732 -
  1.5733 -	int clockTicks = 0;
  1.5734 -	gbDmaTicks = 0;
  1.5735 -
  1.5736 -	register int opcode = 0;
  1.5737 -
  1.5738 -	u32 newmask = 0;
  1.5739 -	if (newFrame)
  1.5740 +  printf("RLM: Inside the GB!\n");
  1.5741 +  gbRegister tempRegister;
  1.5742 +  u8		   tempValue;
  1.5743 +  s8		   offset;
  1.5744 +
  1.5745 +  int clockTicks = 0;
  1.5746 +  gbDmaTicks = 0;
  1.5747 +
  1.5748 +  register int opcode = 0;
  1.5749 +
  1.5750 +  u32 newmask = 0;
  1.5751 +  printf("RLM: newframe = %d\n", newFrame);
  1.5752 +  if (newFrame)
  1.5753 +    {
  1.5754 +      extern void VBAOnExitingFrameBoundary();
  1.5755 +      VBAOnExitingFrameBoundary();
  1.5756 +      printf("RLM: exiting frame boundary?\n");
  1.5757 +      // update joystick information
  1.5758 +      systemReadJoypads();
  1.5759 +
  1.5760 +      bool sensor = (gbRom[0x147] == 0x22);
  1.5761 +
  1.5762 +      // read joystick
  1.5763 +      if (gbSgbMode && gbSgbMultiplayer)
  1.5764  	{
  1.5765 -		extern void VBAOnExitingFrameBoundary();
  1.5766 -		VBAOnExitingFrameBoundary();
  1.5767 -
  1.5768 -		// update joystick information
  1.5769 -		systemReadJoypads();
  1.5770 -
  1.5771 -		bool sensor = (gbRom[0x147] == 0x22);
  1.5772 -
  1.5773 -		// read joystick
  1.5774 -		if (gbSgbMode && gbSgbMultiplayer)
  1.5775 +	  if (gbSgbFourPlayers)
  1.5776 +	    {
  1.5777 +	      gbJoymask[0] = systemGetJoypad(0, sensor);
  1.5778 +	      gbJoymask[1] = systemGetJoypad(1, false);
  1.5779 +	      gbJoymask[2] = systemGetJoypad(2, false);
  1.5780 +	      gbJoymask[3] = systemGetJoypad(3, false);
  1.5781 +	    }
  1.5782 +	  else
  1.5783 +	    {
  1.5784 +	      gbJoymask[0] = systemGetJoypad(0, sensor);
  1.5785 +	      gbJoymask[1] = systemGetJoypad(1, false);
  1.5786 +	    }
  1.5787 +	}
  1.5788 +      else
  1.5789 +	{
  1.5790 +	  gbJoymask[0] = systemGetJoypad(0, sensor);
  1.5791 +	}
  1.5792 +
  1.5793 +      // FIXME: horrible kludge
  1.5794 +      memcpy(s_gbJoymask, gbJoymask, sizeof(gbJoymask));
  1.5795 +
  1.5796 +      //		if (sensor)
  1.5797 +      //			systemUpdateMotionSensor(0);
  1.5798 +
  1.5799 +      newmask = gbJoymask[0];
  1.5800 +      if (newmask & 0xFF)
  1.5801 +	{
  1.5802 +	  gbInterrupt |= 16;
  1.5803 +	}
  1.5804 +
  1.5805 +      extButtons = (newmask >> 18);
  1.5806 +      speedup	   = (extButtons & 1) != 0;
  1.5807 +
  1.5808 +      VBAMovieResetIfRequested();
  1.5809 +      printf("RLM: before Lua functions\n");
  1.5810 +      //CallRegisteredLuaFunctions(LUACALL_BEFOREEMULATION);
  1.5811 +      printf("RLM: after Lua functions\n");
  1.5812 +      newFrame = false;
  1.5813 +    }
  1.5814 +
  1.5815 +
  1.5816 +  for (;; )
  1.5817 +    {
  1.5818 +#ifndef FINAL_VERSION
  1.5819 +      if (systemDebug)
  1.5820 +	{
  1.5821 +	  if (!(IFF & 0x80))
  1.5822 +	    {
  1.5823 +	      if (systemDebug > 1)
  1.5824  		{
  1.5825 -			if (gbSgbFourPlayers)
  1.5826 +		  sprintf(gbBuffer, "PC=%04x AF=%04x BC=%04x DE=%04x HL=%04x SP=%04x I=%04x\n",
  1.5827 +			  PC.W, AF.W, BC.W, DE.W, HL.W, SP.W, IFF);
  1.5828 +		}
  1.5829 +	      else
  1.5830 +		{
  1.5831 +		  sprintf(gbBuffer, "PC=%04x I=%02x\n", PC.W, IFF);
  1.5832 +		}
  1.5833 +	      log(gbBuffer);
  1.5834 +	    }
  1.5835 +	}
  1.5836 +#endif
  1.5837 +      if (IFF & 0x80)
  1.5838 +	{
  1.5839 +	  if (register_LCDC & 0x80)
  1.5840 +	    {
  1.5841 +	      clockTicks = gbLcdTicks;
  1.5842 +	    }
  1.5843 +	  else
  1.5844 +	    clockTicks = 100;
  1.5845 +
  1.5846 +	  if (gbLcdMode == 1 && (gbLcdLYIncrementTicks < clockTicks))
  1.5847 +	    clockTicks = gbLcdLYIncrementTicks;
  1.5848 +
  1.5849 +	  if (gbSerialOn && (gbSerialTicks < clockTicks))
  1.5850 +	    clockTicks = gbSerialTicks;
  1.5851 +
  1.5852 +	  if (gbTimerOn && (gbTimerTicks < clockTicks))
  1.5853 +	    clockTicks = gbTimerTicks;
  1.5854 +
  1.5855 +	  if (soundTicks && (soundTicks < clockTicks))
  1.5856 +	    clockTicks = soundTicks;
  1.5857 +	}
  1.5858 +      else
  1.5859 +	{
  1.5860 +	  opcode = gbReadOpcode(PC.W);
  1.5861 +	  CallRegisteredLuaMemHook(PC.W, 1, opcode, LUAMEMHOOK_EXEC);
  1.5862 +	  PC.W++;
  1.5863 +
  1.5864 +	  if (IFF & 0x100)
  1.5865 +	    {
  1.5866 +	      IFF &= 0xff;
  1.5867 +	      PC.W--;
  1.5868 +	    }
  1.5869 +
  1.5870 +	  clockTicks = gbCycles[opcode];
  1.5871 +
  1.5872 +	  switch (opcode)
  1.5873 +	    {
  1.5874 +	    case 0xCB:
  1.5875 +	      // extended opcode
  1.5876 +	      //CallRegisteredLuaMemHook(PC.W, 1, opcode, LUAMEMHOOK_EXEC);	// is this desired?
  1.5877 +	      opcode	   = gbReadOpcode(PC.W++);
  1.5878 +	      clockTicks = gbCyclesCB[opcode];
  1.5879 +	      switch (opcode)
  1.5880 +		{
  1.5881 +#include "gbCodesCB.h"
  1.5882 +		}
  1.5883 +	      break;
  1.5884 +#include "gbCodes.h"
  1.5885 +	    }
  1.5886 +	}
  1.5887 +
  1.5888 +      if (!emulating)
  1.5889 +	return;
  1.5890 +
  1.5891 +      if (gbDmaTicks)
  1.5892 +	{
  1.5893 +	  clockTicks += gbDmaTicks;
  1.5894 +	  gbDmaTicks	= 0;
  1.5895 +	}
  1.5896 +
  1.5897 +      if (gbSgbMode)
  1.5898 +	{
  1.5899 +	  if (gbSgbPacketTimeout)
  1.5900 +	    {
  1.5901 +	      gbSgbPacketTimeout -= clockTicks;
  1.5902 +
  1.5903 +	      if (gbSgbPacketTimeout <= 0)
  1.5904 +		gbSgbResetPacketState();
  1.5905 +	    }
  1.5906 +	}
  1.5907 +
  1.5908 +      ticksToStop -= clockTicks;
  1.5909 +
  1.5910 +      // DIV register emulation
  1.5911 +      gbDivTicks -= clockTicks;
  1.5912 +      while (gbDivTicks <= 0)
  1.5913 +	{
  1.5914 +	  register_DIV++;
  1.5915 +	  gbDivTicks += GBDIV_CLOCK_TICKS;
  1.5916 +	}
  1.5917 +
  1.5918 +      if (register_LCDC & 0x80)
  1.5919 +	{
  1.5920 +	  // LCD stuff
  1.5921 +	  gbLcdTicks -= clockTicks;
  1.5922 +	  if (gbLcdMode == 1)
  1.5923 +	    {
  1.5924 +	      // during V-BLANK,we need to increment LY at the same rate!
  1.5925 +	      gbLcdLYIncrementTicks -= clockTicks;
  1.5926 +	      while (gbLcdLYIncrementTicks <= 0)
  1.5927 +		{
  1.5928 +		  gbLcdLYIncrementTicks += GBLY_INCREMENT_CLOCK_TICKS;
  1.5929 +
  1.5930 +		  if (register_LY < 153)
  1.5931 +		    {
  1.5932 +		      register_LY++;
  1.5933 +
  1.5934 +		      gbCompareLYToLYC();
  1.5935 +
  1.5936 +		      if (register_LY >= 153)
  1.5937 +			gbLcdLYIncrementTicks = 6;
  1.5938 +		    }
  1.5939 +		  else
  1.5940 +		    {
  1.5941 +		      register_LY = 0x00;
  1.5942 +		      // reset the window line
  1.5943 +		      gbWindowLine = -1;
  1.5944 +		      gbLcdLYIncrementTicks = GBLY_INCREMENT_CLOCK_TICKS * 2;
  1.5945 +		      gbCompareLYToLYC();
  1.5946 +		    }
  1.5947 +		}
  1.5948 +	    }
  1.5949 +
  1.5950 +	  // our counter is off, see what we need to do
  1.5951 +	  while (gbLcdTicks <= 0)
  1.5952 +	    {
  1.5953 +	      int framesToSkip = systemFramesToSkip();
  1.5954 +
  1.5955 +	      switch (gbLcdMode)
  1.5956 +		{
  1.5957 +		case 0:
  1.5958 +		  // H-Blank
  1.5959 +		  register_LY++;
  1.5960 +
  1.5961 +		  gbCompareLYToLYC();
  1.5962 +
  1.5963 +		  // check if we reached the V-Blank period
  1.5964 +		  if (register_LY == 144)
  1.5965 +		    {
  1.5966 +		      // Yes, V-Blank
  1.5967 +		      // set the LY increment counter
  1.5968 +		      gbLcdLYIncrementTicks = gbLcdTicks + GBLY_INCREMENT_CLOCK_TICKS;
  1.5969 +		      gbLcdTicks += GBLCD_MODE_1_CLOCK_TICKS;
  1.5970 +		      gbLcdMode	= 1;
  1.5971 +		      if (register_LCDC & 0x80)
  1.5972  			{
  1.5973 -				gbJoymask[0] = systemGetJoypad(0, sensor);
  1.5974 -				gbJoymask[1] = systemGetJoypad(1, false);
  1.5975 -				gbJoymask[2] = systemGetJoypad(2, false);
  1.5976 -				gbJoymask[3] = systemGetJoypad(3, false);
  1.5977 +			  gbInterrupt	   |= 1; // V-Blank interrupt
  1.5978 +			  gbInterruptWait = 6;
  1.5979 +			  if (register_STAT & 0x10)
  1.5980 +			    gbInterrupt |= 2;
  1.5981  			}
  1.5982 -			else
  1.5983 +
  1.5984 +		      systemFrame();
  1.5985 +
  1.5986 +		      ++gbFrameCount;
  1.5987 +		      u32 currentTime = systemGetClock();
  1.5988 +		      if (currentTime - gbLastTime >= 1000)
  1.5989  			{
  1.5990 -				gbJoymask[0] = systemGetJoypad(0, sensor);
  1.5991 -				gbJoymask[1] = systemGetJoypad(1, false);
  1.5992 +			  systemShowSpeed(int(float(gbFrameCount) * 100000 / (float(currentTime - gbLastTime) * 60) + .5f));
  1.5993 +			  gbLastTime	 = currentTime;
  1.5994 +			  gbFrameCount = 0;
  1.5995  			}
  1.5996 +
  1.5997 +		      ++GBSystemCounters.frameCount;
  1.5998 +		      if (GBSystemCounters.lagged)
  1.5999 +			{
  1.6000 +			  ++GBSystemCounters.lagCount;
  1.6001 +			}
  1.6002 +		      GBSystemCounters.laggedLast = GBSystemCounters.lagged;
  1.6003 +		      GBSystemCounters.lagged		= true;
  1.6004 +
  1.6005 +		      extern void VBAOnEnteringFrameBoundary();
  1.6006 +		      VBAOnEnteringFrameBoundary();
  1.6007 +
  1.6008 +		      newFrame = true;
  1.6009 +
  1.6010 +		      pauseAfterFrameAdvance = systemPauseOnFrame();
  1.6011 +
  1.6012 +		      if (gbFrameSkipCount >= framesToSkip || pauseAfterFrameAdvance)
  1.6013 +			{
  1.6014 +			  if (gbBorderOn)
  1.6015 +			    gbSgbRenderBorder();  // clear unnecessary things on border (e.g. in-game text message)
  1.6016 +
  1.6017 +			  systemRenderFrame();
  1.6018 +			  gbFrameSkipCount = 0;
  1.6019 +
  1.6020 +			  bool capturePressed = (extButtons & 2) != 0;
  1.6021 +			  if (capturePressed && !capturePrevious)
  1.6022 +			    {
  1.6023 +			      captureNumber = systemScreenCapture(captureNumber);
  1.6024 +			    }
  1.6025 +			  capturePrevious = capturePressed && !pauseAfterFrameAdvance;
  1.6026 +			}
  1.6027 +		      else
  1.6028 +			{
  1.6029 +			  ++gbFrameSkipCount;
  1.6030 +			}
  1.6031 +
  1.6032 +		      if (pauseAfterFrameAdvance)
  1.6033 +			{
  1.6034 +			  systemSetPause(true);
  1.6035 +			}
  1.6036 +		    }
  1.6037 +		  else
  1.6038 +		    {
  1.6039 +		      // go the the OAM being accessed mode
  1.6040 +		      gbLcdTicks += GBLCD_MODE_2_CLOCK_TICKS;
  1.6041 +		      gbLcdMode	= 2;
  1.6042 +
  1.6043 +		      // only one LCD interrupt per line. may need to generalize...
  1.6044 +		      if (!(register_STAT & 0x40) ||
  1.6045 +			  (register_LY != register_LYC))
  1.6046 +			{
  1.6047 +			  if ((register_STAT & 0x28) == 0x20)
  1.6048 +			    gbInterrupt |= 2;
  1.6049 +			}
  1.6050 +		    }
  1.6051 +
  1.6052 +		  break;
  1.6053 +		case 1:
  1.6054 +		  // V-Blank
  1.6055 +		  // next mode is OAM being accessed mode
  1.6056 +		  gbLcdTicks += GBLCD_MODE_2_CLOCK_TICKS;
  1.6057 +		  gbLcdMode	= 2;
  1.6058 +		  if (!(register_STAT & 0x40) ||
  1.6059 +		      (register_LY != register_LYC))
  1.6060 +		    {
  1.6061 +		      if ((register_STAT & 0x28) == 0x20)
  1.6062 +			gbInterrupt |= 2;
  1.6063 +		    }
  1.6064 +		  break;
  1.6065 +		case 2:
  1.6066 +		  // OAM being accessed mode
  1.6067 +
  1.6068 +		  // next mode is OAM and VRAM in use
  1.6069 +		  gbLcdTicks += GBLCD_MODE_3_CLOCK_TICKS;
  1.6070 +		  gbLcdMode	= 3;
  1.6071 +		  break;
  1.6072 +		case 3:
  1.6073 +		  // OAM and VRAM in use
  1.6074 +		  // next mode is H-Blank
  1.6075 +		  if (register_LY < 144)
  1.6076 +		    {
  1.6077 +		      if (!gbSgbMask)
  1.6078 +			{
  1.6079 +			  if (gbFrameSkipCount >= framesToSkip || pauseAfterFrameAdvance)
  1.6080 +			    {
  1.6081 +			      gbRenderLine();
  1.6082 +			      gbDrawSprites();
  1.6083 +
  1.6084 +			      switch (systemColorDepth)
  1.6085 +				{
  1.6086 +				case 16:
  1.6087 +
  1.6088 +				  {
  1.6089 +				    u16 *dest = (u16 *)pix +
  1.6090 +				      (gbBorderLineSkip + 2) * (register_LY + gbBorderRowSkip + 1)
  1.6091 +				      + gbBorderColumnSkip;
  1.6092 +				    for (int x = 0; x < 160; )
  1.6093 +				      {
  1.6094 +					*dest++ = systemColorMap16[gbLineMix[x++]];
  1.6095 +					*dest++ = systemColorMap16[gbLineMix[x++]];
  1.6096 +					*dest++ = systemColorMap16[gbLineMix[x++]];
  1.6097 +					*dest++ = systemColorMap16[gbLineMix[x++]];
  1.6098 +
  1.6099 +					*dest++ = systemColorMap16[gbLineMix[x++]];
  1.6100 +					*dest++ = systemColorMap16[gbLineMix[x++]];
  1.6101 +					*dest++ = systemColorMap16[gbLineMix[x++]];
  1.6102 +					*dest++ = systemColorMap16[gbLineMix[x++]];
  1.6103 +
  1.6104 +					*dest++ = systemColorMap16[gbLineMix[x++]];
  1.6105 +					*dest++ = systemColorMap16[gbLineMix[x++]];
  1.6106 +					*dest++ = systemColorMap16[gbLineMix[x++]];
  1.6107 +					*dest++ = systemColorMap16[gbLineMix[x++]];
  1.6108 +
  1.6109 +					*dest++ = systemColorMap16[gbLineMix[x++]];
  1.6110 +					*dest++ = systemColorMap16[gbLineMix[x++]];
  1.6111 +					*dest++ = systemColorMap16[gbLineMix[x++]];
  1.6112 +					*dest++ = systemColorMap16[gbLineMix[x++]];
  1.6113 +				      }
  1.6114 +				    if (gbBorderOn)
  1.6115 +				      dest += gbBorderColumnSkip;
  1.6116 +				    *dest++ = 0;     // for filters that read one pixel more
  1.6117 +				    break;
  1.6118 +				  }
  1.6119 +				case 24:
  1.6120 +
  1.6121 +				  {
  1.6122 +				    u8 *dest = (u8 *)pix +
  1.6123 +				      3 * (gbBorderLineSkip * (register_LY + gbBorderRowSkip) +
  1.6124 +					   gbBorderColumnSkip);
  1.6125 +				    for (int x = 0; x < 160; )
  1.6126 +				      {
  1.6127 +					*((u32 *)dest) = systemColorMap32[gbLineMix[x++]];
  1.6128 +					dest += 3;
  1.6129 +					*((u32 *)dest) = systemColorMap32[gbLineMix[x++]];
  1.6130 +					dest += 3;
  1.6131 +					*((u32 *)dest) = systemColorMap32[gbLineMix[x++]];
  1.6132 +					dest += 3;
  1.6133 +					*((u32 *)dest) = systemColorMap32[gbLineMix[x++]];
  1.6134 +					dest += 3;
  1.6135 +
  1.6136 +					*((u32 *)dest) = systemColorMap32[gbLineMix[x++]];
  1.6137 +					dest += 3;
  1.6138 +					*((u32 *)dest) = systemColorMap32[gbLineMix[x++]];
  1.6139 +					dest += 3;
  1.6140 +					*((u32 *)dest) = systemColorMap32[gbLineMix[x++]];
  1.6141 +					dest += 3;
  1.6142 +					*((u32 *)dest) = systemColorMap32[gbLineMix[x++]];
  1.6143 +					dest += 3;
  1.6144 +
  1.6145 +					*((u32 *)dest) = systemColorMap32[gbLineMix[x++]];
  1.6146 +					dest += 3;
  1.6147 +					*((u32 *)dest) = systemColorMap32[gbLineMix[x++]];
  1.6148 +					dest += 3;
  1.6149 +					*((u32 *)dest) = systemColorMap32[gbLineMix[x++]];
  1.6150 +					dest += 3;
  1.6151 +					*((u32 *)dest) = systemColorMap32[gbLineMix[x++]];
  1.6152 +					dest += 3;
  1.6153 +
  1.6154 +					*((u32 *)dest) = systemColorMap32[gbLineMix[x++]];
  1.6155 +					dest += 3;
  1.6156 +					*((u32 *)dest) = systemColorMap32[gbLineMix[x++]];
  1.6157 +					dest += 3;
  1.6158 +					*((u32 *)dest) = systemColorMap32[gbLineMix[x++]];
  1.6159 +					dest += 3;
  1.6160 +					*((u32 *)dest) = systemColorMap32[gbLineMix[x++]];
  1.6161 +					dest += 3;
  1.6162 +				      }
  1.6163 +				    break;
  1.6164 +				  }
  1.6165 +				case 32:
  1.6166 +
  1.6167 +				  {
  1.6168 +				    u32 *dest = (u32 *)pix +
  1.6169 +				      (gbBorderLineSkip + 1) * (register_LY + gbBorderRowSkip + 1)
  1.6170 +				      + gbBorderColumnSkip;
  1.6171 +				    for (int x = 0; x < 160; )
  1.6172 +				      {
  1.6173 +					*dest++ = systemColorMap32[gbLineMix[x++]];
  1.6174 +					*dest++ = systemColorMap32[gbLineMix[x++]];
  1.6175 +					*dest++ = systemColorMap32[gbLineMix[x++]];
  1.6176 +					*dest++ = systemColorMap32[gbLineMix[x++]];
  1.6177 +
  1.6178 +					*dest++ = systemColorMap32[gbLineMix[x++]];
  1.6179 +					*dest++ = systemColorMap32[gbLineMix[x++]];
  1.6180 +					*dest++ = systemColorMap32[gbLineMix[x++]];
  1.6181 +					*dest++ = systemColorMap32[gbLineMix[x++]];
  1.6182 +
  1.6183 +					*dest++ = systemColorMap32[gbLineMix[x++]];
  1.6184 +					*dest++ = systemColorMap32[gbLineMix[x++]];
  1.6185 +					*dest++ = systemColorMap32[gbLineMix[x++]];
  1.6186 +					*dest++ = systemColorMap32[gbLineMix[x++]];
  1.6187 +
  1.6188 +					*dest++ = systemColorMap32[gbLineMix[x++]];
  1.6189 +					*dest++ = systemColorMap32[gbLineMix[x++]];
  1.6190 +					*dest++ = systemColorMap32[gbLineMix[x++]];
  1.6191 +					*dest++ = systemColorMap32[gbLineMix[x++]];
  1.6192 +				      }
  1.6193 +				    break;
  1.6194 +				  }
  1.6195 +				}
  1.6196 +			    }
  1.6197 +			}
  1.6198 +		    }
  1.6199 +		  gbLcdTicks += GBLCD_MODE_0_CLOCK_TICKS;
  1.6200 +		  gbLcdMode	= 0;
  1.6201 +		  // only one LCD interrupt per line. may need to generalize...
  1.6202 +		  if (!(register_STAT & 0x40) ||
  1.6203 +		      (register_LY != register_LYC))
  1.6204 +		    {
  1.6205 +		      if (register_STAT & 0x08)
  1.6206 +			gbInterrupt |= 2;
  1.6207 +		    }
  1.6208 +		  if (gbHdmaOn)
  1.6209 +		    {
  1.6210 +		      gbDoHdma();
  1.6211 +		    }
  1.6212 +		  break;
  1.6213  		}
  1.6214 -		else
  1.6215 +	      // mark the correct lcd mode on STAT register
  1.6216 +	      register_STAT = (register_STAT & 0xfc) | gbLcdMode;
  1.6217 +	    }
  1.6218 +	}
  1.6219 +
  1.6220 +      // serial emulation
  1.6221 +      if (gbSerialOn)
  1.6222 +	{
  1.6223 +#ifdef LINK_EMULATION
  1.6224 +	  if (linkConnected)
  1.6225 +	    {
  1.6226 +	      gbSerialTicks -= clockTicks;
  1.6227 +
  1.6228 +	      while (gbSerialTicks <= 0)
  1.6229  		{
  1.6230 -			gbJoymask[0] = systemGetJoypad(0, sensor);
  1.6231 +		  // increment number of shifted bits
  1.6232 +		  gbSerialBits++;
  1.6233 +		  linkProc();
  1.6234 +		  if (gbSerialOn && (gbMemory[0xff02] & 1))
  1.6235 +		    {
  1.6236 +		      if (gbSerialBits == 8)
  1.6237 +			{
  1.6238 +			  gbSerialBits	  = 0;
  1.6239 +			  gbMemory[0xff01]  = 0xff;
  1.6240 +			  gbMemory[0xff02] &= 0x7f;
  1.6241 +			  gbSerialOn		  = 0;
  1.6242 +			  gbInterrupt		 |= 8;
  1.6243 +			  gbSerialTicks	  = 0;
  1.6244 +			}
  1.6245 +		    }
  1.6246 +		  gbSerialTicks += GBSERIAL_CLOCK_TICKS;
  1.6247  		}
  1.6248 -
  1.6249 -		// FIXME: horrible kludge
  1.6250 -		memcpy(s_gbJoymask, gbJoymask, sizeof(gbJoymask));
  1.6251 -
  1.6252 -//		if (sensor)
  1.6253 -//			systemUpdateMotionSensor(0);
  1.6254 -
  1.6255 -		newmask = gbJoymask[0];
  1.6256 -		if (newmask & 0xFF)
  1.6257 +	    }
  1.6258 +	  else
  1.6259 +	    {
  1.6260 +#endif
  1.6261 +	      if (gbMemory[0xff02] & 1)
  1.6262  		{
  1.6263 -			gbInterrupt |= 16;
  1.6264 +		  gbSerialTicks -= clockTicks;
  1.6265 +
  1.6266 +		  // overflow
  1.6267 +		  while (gbSerialTicks <= 0)
  1.6268 +		    {
  1.6269 +		      // shift serial byte to right and put a 1 bit in its place
  1.6270 +		      //      gbMemory[0xff01] = 0x80 | (gbMemory[0xff01]>>1);
  1.6271 +		      // increment number of shifted bits
  1.6272 +		      gbSerialBits++;
  1.6273 +		      if (gbSerialBits == 8)
  1.6274 +			{
  1.6275 +			  // end of transmission
  1.6276 +			  if (gbSerialFunction)    // external device
  1.6277 +			    gbMemory[0xff01] = gbSerialFunction(gbMemory[0xff01]);
  1.6278 +			  else
  1.6279 +			    gbMemory[0xff01] = 0xff;
  1.6280 +			  gbSerialTicks	  = 0;
  1.6281 +			  gbMemory[0xff02] &= 0x7f;
  1.6282 +			  gbSerialOn		  = 0;
  1.6283 +			  gbInterrupt		 |= 8;
  1.6284 +			  gbSerialBits	  = 0;
  1.6285 +			}
  1.6286 +		      else
  1.6287 +			gbSerialTicks += GBSERIAL_CLOCK_TICKS;
  1.6288 +		    }
  1.6289  		}
  1.6290 -
  1.6291 -		extButtons = (newmask >> 18);
  1.6292 -		speedup	   = (extButtons & 1) != 0;
  1.6293 -
  1.6294 -		VBAMovieResetIfRequested();
  1.6295 -
  1.6296 -		CallRegisteredLuaFunctions(LUACALL_BEFOREEMULATION);
  1.6297 -
  1.6298 -		newFrame = false;
  1.6299 +#ifdef LINK_EMULATION
  1.6300 +	    }
  1.6301 +#endif
  1.6302  	}
  1.6303  
  1.6304 -	for (;; )
  1.6305 +      // timer emulation
  1.6306 +      if (gbTimerOn)
  1.6307  	{
  1.6308 -#ifndef FINAL_VERSION
  1.6309 -		if (systemDebug)
  1.6310 +	  gbTimerTicks -= clockTicks;
  1.6311 +
  1.6312 +	  while (gbTimerTicks <= 0)
  1.6313 +	    {
  1.6314 +	      register_TIMA++;
  1.6315 +
  1.6316 +	      if (register_TIMA == 0)
  1.6317  		{
  1.6318 -			if (!(IFF & 0x80))
  1.6319 +		  // timer overflow!
  1.6320 +
  1.6321 +		  // reload timer modulo
  1.6322 +		  register_TIMA = register_TMA;
  1.6323 +
  1.6324 +		  // flag interrupt
  1.6325 +		  gbInterrupt |= 4;
  1.6326 +		}
  1.6327 +
  1.6328 +	      gbTimerTicks += gbTimerClockTicks;
  1.6329 +	    }
  1.6330 +	}
  1.6331 +
  1.6332 +      /*
  1.6333 +	if(soundOffFlag)
  1.6334 +	{
  1.6335 +	if(synchronize && !speedup)
  1.6336 +	{
  1.6337 +	synchronizeTicks -= clockTicks;
  1.6338 +
  1.6339 +	while(synchronizeTicks < 0)
  1.6340 +	{
  1.6341 +	synchronizeTicks += SYNCHRONIZE_CLOCK_TICKS;
  1.6342 +
  1.6343 +	DWORD now = timeGetTime();
  1.6344 +	gbElapsedTime += (now - timeNow);
  1.6345 +
  1.6346 +	if(gbElapsedTime < 50)
  1.6347 +	{
  1.6348 +	DWORD diff = 50 - gbElapsedTime;
  1.6349 +	Sleep(diff);
  1.6350 +	timeNow = timeGetTime();
  1.6351 +	elapsedTime = timeNow - now - diff;
  1.6352 +	if((int)elapsedTime < 0)
  1.6353 +	elapsedTime = 0;
  1.6354 +	} else
  1.6355 +	{
  1.6356 +	timeNow = timeGetTime();
  1.6357 +	elapsedTime = 0;
  1.6358 +	}
  1.6359 +	}
  1.6360 +	}
  1.6361 +	}
  1.6362 +      */
  1.6363 +
  1.6364 +      soundTicks -= clockTicks;
  1.6365 +      while (soundTicks < 0) // must be < 1 when soundtick_t is real data type
  1.6366 +	{
  1.6367 +	  soundTicks += SOUND_CLOCK_TICKS;
  1.6368 +
  1.6369 +	  gbSoundTick();
  1.6370 +	}
  1.6371 +
  1.6372 +      register_IF = gbInterrupt;
  1.6373 +
  1.6374 +      if (IFF & 0x20)
  1.6375 +	{
  1.6376 +	  IFF &= 0xdf;
  1.6377 +	  IFF |= 0x01;
  1.6378 +	  gbInterruptWait = 0;
  1.6379 +	}
  1.6380 +      else if (gbInterrupt)
  1.6381 +	{
  1.6382 +	  if (gbInterruptWait == 0)
  1.6383 +	    {
  1.6384 +	      //        gbInterruptWait = 0;
  1.6385 +
  1.6386 +	      if (IFF & 0x01)
  1.6387 +		{
  1.6388 +		  if ((gbInterrupt & 1) && (register_IE & 1))
  1.6389 +		    {
  1.6390 +		      gbVblank_interrupt();
  1.6391 +		      continue;
  1.6392 +		    }
  1.6393 +
  1.6394 +		  if ((gbInterrupt & 2) && (register_IE & 2))
  1.6395 +		    {
  1.6396 +		      gbLcd_interrupt();
  1.6397 +		      continue;
  1.6398 +		    }
  1.6399 +
  1.6400 +		  if ((gbInterrupt & 4) && (register_IE & 4))
  1.6401 +		    {
  1.6402 +		      gbTimer_interrupt();
  1.6403 +		      continue;
  1.6404 +		    }
  1.6405 +
  1.6406 +		  if ((gbInterrupt & 8) && (register_IE & 8))
  1.6407 +		    {
  1.6408 +		      gbSerial_interrupt();
  1.6409 +		      continue;
  1.6410 +		    }
  1.6411 +
  1.6412 +		  if ((gbInterrupt & 16) && (register_IE & 16))
  1.6413 +		    {
  1.6414 +		      gbJoypad_interrupt();
  1.6415 +		      continue;
  1.6416 +		    }
  1.6417 +		}
  1.6418 +	    }
  1.6419 +	  else
  1.6420 +	    {
  1.6421 +	      gbInterruptWait -= clockTicks;
  1.6422 +	      if (gbInterruptWait < 0)
  1.6423 +		gbInterruptWait = 0;
  1.6424 +	    }
  1.6425 +	}
  1.6426 +
  1.6427 +      if (useOldFrameTiming)
  1.6428 +	{
  1.6429 +	  // old timing code
  1.6430 +	  if (ticksToStop > 0)
  1.6431 +	    continue;
  1.6432 +	}
  1.6433 +      else
  1.6434 +	{
  1.6435 +	  if (!newFrame && (register_LCDC & 0x80) != 0)
  1.6436 +	    continue;
  1.6437 +	}
  1.6438 +
  1.6439 +      if (!(register_LCDC & 0x80))
  1.6440 +	{
  1.6441 +	  if (!useOldFrameTiming)
  1.6442 +	    {
  1.6443 +	      // FIXME: since register_LY can be reset to 0 by some games, frame length is variable
  1.6444 +	      // and infinite loops can occurr
  1.6445 +	      // for now, it IS necessary to do something on this condition or games like
  1.6446 +	      // Megaman would freeze upon low-level restart interrupt sequence (Start+Select+A+B).
  1.6447 +	      // the only sensible way to fix this issue is to implement the RIGHT frame timing
  1.6448 +#ifdef WANTS_INCOMPLETE_WORKAROUND
  1.6449 +	      if (systemReadJoypads())
  1.6450 +		{
  1.6451 +		  if (gbSgbMode && gbSgbMultiplayer)
  1.6452 +		    {
  1.6453 +		      if (gbSgbFourPlayers)
  1.6454  			{
  1.6455 -				if (systemDebug > 1)
  1.6456 -				{
  1.6457 -					sprintf(gbBuffer, "PC=%04x AF=%04x BC=%04x DE=%04x HL=%04x SP=%04x I=%04x\n",
  1.6458 -					        PC.W, AF.W, BC.W, DE.W, HL.W, SP.W, IFF);
  1.6459 -				}
  1.6460 -				else
  1.6461 -				{
  1.6462 -					sprintf(gbBuffer, "PC=%04x I=%02x\n", PC.W, IFF);
  1.6463 -				}
  1.6464 -				log(gbBuffer);
  1.6465 +			  gbJoymask[0] = systemGetJoypad(0, false);
  1.6466 +			  gbJoymask[1] = systemGetJoypad(1, false);
  1.6467 +			  gbJoymask[2] = systemGetJoypad(2, false);
  1.6468 +			  gbJoymask[3] = systemGetJoypad(3, false);
  1.6469  			}
  1.6470 +		      else
  1.6471 +			{
  1.6472 +			  gbJoymask[0] = systemGetJoypad(0, false);
  1.6473 +			  gbJoymask[1] = systemGetJoypad(1, false);
  1.6474 +			}
  1.6475 +		    }
  1.6476 +		  else
  1.6477 +		    {
  1.6478 +		      gbJoymask[0] = systemGetJoypad(0, false);
  1.6479 +		    }
  1.6480  		}
  1.6481 -#endif
  1.6482 -		if (IFF & 0x80)
  1.6483 -		{
  1.6484 -			if (register_LCDC & 0x80)
  1.6485 -			{
  1.6486 -				clockTicks = gbLcdTicks;
  1.6487 -			}
  1.6488 -			else
  1.6489 -				clockTicks = 100;
  1.6490 -
  1.6491 -			if (gbLcdMode == 1 && (gbLcdLYIncrementTicks < clockTicks))
  1.6492 -				clockTicks = gbLcdLYIncrementTicks;
  1.6493 -
  1.6494 -			if (gbSerialOn && (gbSerialTicks < clockTicks))
  1.6495 -				clockTicks = gbSerialTicks;
  1.6496 -
  1.6497 -			if (gbTimerOn && (gbTimerTicks < clockTicks))
  1.6498 -				clockTicks = gbTimerTicks;
  1.6499 -
  1.6500 -			if (soundTicks && (soundTicks < clockTicks))
  1.6501 -				clockTicks = soundTicks;
  1.6502 -		}
  1.6503 -		else
  1.6504 -		{
  1.6505 -			opcode = gbReadOpcode(PC.W);
  1.6506 -			CallRegisteredLuaMemHook(PC.W, 1, opcode, LUAMEMHOOK_EXEC);
  1.6507 -			PC.W++;
  1.6508 -
  1.6509 -			if (IFF & 0x100)
  1.6510 -			{
  1.6511 -				IFF &= 0xff;
  1.6512 -				PC.W--;
  1.6513 -			}
  1.6514 -
  1.6515 -			clockTicks = gbCycles[opcode];
  1.6516 -
  1.6517 -			switch (opcode)
  1.6518 -			{
  1.6519 -			case 0xCB:
  1.6520 -				// extended opcode
  1.6521 -				//CallRegisteredLuaMemHook(PC.W, 1, opcode, LUAMEMHOOK_EXEC);	// is this desired?
  1.6522 -				opcode	   = gbReadOpcode(PC.W++);
  1.6523 -				clockTicks = gbCyclesCB[opcode];
  1.6524 -				switch (opcode)
  1.6525 -				{
  1.6526 -#include "gbCodesCB.h"
  1.6527 -				}
  1.6528 -				break;
  1.6529 -#include "gbCodes.h"
  1.6530 -			}
  1.6531 -		}
  1.6532 -
  1.6533 -		if (!emulating)
  1.6534 -			return;
  1.6535 -
  1.6536 -		if (gbDmaTicks)
  1.6537 -		{
  1.6538 -			clockTicks += gbDmaTicks;
  1.6539 -			gbDmaTicks	= 0;
  1.6540 -		}
  1.6541 -
  1.6542 -		if (gbSgbMode)
  1.6543 -		{
  1.6544 -			if (gbSgbPacketTimeout)
  1.6545 -			{
  1.6546 -				gbSgbPacketTimeout -= clockTicks;
  1.6547 -
  1.6548 -				if (gbSgbPacketTimeout <= 0)
  1.6549 -					gbSgbResetPacketState();
  1.6550 -			}
  1.6551 -		}
  1.6552 -
  1.6553 -		ticksToStop -= clockTicks;
  1.6554 -
  1.6555 -		// DIV register emulation
  1.6556 -		gbDivTicks -= clockTicks;
  1.6557 -		while (gbDivTicks <= 0)
  1.6558 -		{
  1.6559 -			register_DIV++;
  1.6560 -			gbDivTicks += GBDIV_CLOCK_TICKS;
  1.6561 -		}
  1.6562 -
  1.6563 -		if (register_LCDC & 0x80)
  1.6564 -		{
  1.6565 -			// LCD stuff
  1.6566 -			gbLcdTicks -= clockTicks;
  1.6567 -			if (gbLcdMode == 1)
  1.6568 -			{
  1.6569 -				// during V-BLANK,we need to increment LY at the same rate!
  1.6570 -				gbLcdLYIncrementTicks -= clockTicks;
  1.6571 -				while (gbLcdLYIncrementTicks <= 0)
  1.6572 -				{
  1.6573 -					gbLcdLYIncrementTicks += GBLY_INCREMENT_CLOCK_TICKS;
  1.6574 -
  1.6575 -					if (register_LY < 153)
  1.6576 -					{
  1.6577 -						register_LY++;
  1.6578 -
  1.6579 -						gbCompareLYToLYC();
  1.6580 -
  1.6581 -						if (register_LY >= 153)
  1.6582 -							gbLcdLYIncrementTicks = 6;
  1.6583 -					}
  1.6584 -					else
  1.6585 -					{
  1.6586 -						register_LY = 0x00;
  1.6587 -						// reset the window line
  1.6588 -						gbWindowLine = -1;
  1.6589 -						gbLcdLYIncrementTicks = GBLY_INCREMENT_CLOCK_TICKS * 2;
  1.6590 -						gbCompareLYToLYC();
  1.6591 -					}
  1.6592 -				}
  1.6593 -			}
  1.6594 -
  1.6595 -			// our counter is off, see what we need to do
  1.6596 -			while (gbLcdTicks <= 0)
  1.6597 -			{
  1.6598 -				int framesToSkip = systemFramesToSkip();
  1.6599 -
  1.6600 -				switch (gbLcdMode)
  1.6601 -				{
  1.6602 -				case 0:
  1.6603 -					// H-Blank
  1.6604 -					register_LY++;
  1.6605 -
  1.6606 -					gbCompareLYToLYC();
  1.6607 -
  1.6608 -					// check if we reached the V-Blank period
  1.6609 -					if (register_LY == 144)
  1.6610 -					{
  1.6611 -						// Yes, V-Blank
  1.6612 -						// set the LY increment counter
  1.6613 -						gbLcdLYIncrementTicks = gbLcdTicks + GBLY_INCREMENT_CLOCK_TICKS;
  1.6614 -						gbLcdTicks += GBLCD_MODE_1_CLOCK_TICKS;
  1.6615 -						gbLcdMode	= 1;
  1.6616 -						if (register_LCDC & 0x80)
  1.6617 -						{
  1.6618 -							gbInterrupt	   |= 1; // V-Blank interrupt
  1.6619 -							gbInterruptWait = 6;
  1.6620 -							if (register_STAT & 0x10)
  1.6621 -								gbInterrupt |= 2;
  1.6622 -						}
  1.6623 -
  1.6624 -						systemFrame();
  1.6625 -
  1.6626 -						++gbFrameCount;
  1.6627 -						u32 currentTime = systemGetClock();
  1.6628 -						if (currentTime - gbLastTime >= 1000)
  1.6629 -						{
  1.6630 -							systemShowSpeed(int(float(gbFrameCount) * 100000 / (float(currentTime - gbLastTime) * 60) + .5f));
  1.6631 -							gbLastTime	 = currentTime;
  1.6632 -							gbFrameCount = 0;
  1.6633 -						}
  1.6634 -
  1.6635 -						++GBSystemCounters.frameCount;
  1.6636 -						if (GBSystemCounters.lagged)
  1.6637 -						{
  1.6638 -							++GBSystemCounters.lagCount;
  1.6639 -						}
  1.6640 -						GBSystemCounters.laggedLast = GBSystemCounters.lagged;
  1.6641 -						GBSystemCounters.lagged		= true;
  1.6642 -
  1.6643 -						extern void VBAOnEnteringFrameBoundary();
  1.6644 -						VBAOnEnteringFrameBoundary();
  1.6645 -
  1.6646 -						newFrame = true;
  1.6647 -
  1.6648 -						pauseAfterFrameAdvance = systemPauseOnFrame();
  1.6649 -
  1.6650 -						if (gbFrameSkipCount >= framesToSkip || pauseAfterFrameAdvance)
  1.6651 -						{
  1.6652 -							if (gbBorderOn)
  1.6653 -								gbSgbRenderBorder();  // clear unnecessary things on border (e.g. in-game text message)
  1.6654 -
  1.6655 -							systemRenderFrame();
  1.6656 -							gbFrameSkipCount = 0;
  1.6657 -
  1.6658 -							bool capturePressed = (extButtons & 2) != 0;
  1.6659 -							if (capturePressed && !capturePrevious)
  1.6660 -							{
  1.6661 -								captureNumber = systemScreenCapture(captureNumber);
  1.6662 -							}
  1.6663 -							capturePrevious = capturePressed && !pauseAfterFrameAdvance;
  1.6664 -						}
  1.6665 -						else
  1.6666 -						{
  1.6667 -							++gbFrameSkipCount;
  1.6668 -						}
  1.6669 -
  1.6670 -						if (pauseAfterFrameAdvance)
  1.6671 -						{
  1.6672 -							systemSetPause(true);
  1.6673 -						}
  1.6674 -					}
  1.6675 -					else
  1.6676 -					{
  1.6677 -						// go the the OAM being accessed mode
  1.6678 -						gbLcdTicks += GBLCD_MODE_2_CLOCK_TICKS;
  1.6679 -						gbLcdMode	= 2;
  1.6680 -
  1.6681 -						// only one LCD interrupt per line. may need to generalize...
  1.6682 -						if (!(register_STAT & 0x40) ||
  1.6683 -						    (register_LY != register_LYC))
  1.6684 -						{
  1.6685 -							if ((register_STAT & 0x28) == 0x20)
  1.6686 -								gbInterrupt |= 2;
  1.6687 -						}
  1.6688 -					}
  1.6689 -
  1.6690 -					break;
  1.6691 -				case 1:
  1.6692 -					// V-Blank
  1.6693 -					// next mode is OAM being accessed mode
  1.6694 -					gbLcdTicks += GBLCD_MODE_2_CLOCK_TICKS;
  1.6695 -					gbLcdMode	= 2;
  1.6696 -					if (!(register_STAT & 0x40) ||
  1.6697 -					    (register_LY != register_LYC))
  1.6698 -					{
  1.6699 -						if ((register_STAT & 0x28) == 0x20)
  1.6700 -							gbInterrupt |= 2;
  1.6701 -					}
  1.6702 -					break;
  1.6703 -				case 2:
  1.6704 -					// OAM being accessed mode
  1.6705 -
  1.6706 -					// next mode is OAM and VRAM in use
  1.6707 -					gbLcdTicks += GBLCD_MODE_3_CLOCK_TICKS;
  1.6708 -					gbLcdMode	= 3;
  1.6709 -					break;
  1.6710 -				case 3:
  1.6711 -					// OAM and VRAM in use
  1.6712 -					// next mode is H-Blank
  1.6713 -					if (register_LY < 144)
  1.6714 -					{
  1.6715 -						if (!gbSgbMask)
  1.6716 -						{
  1.6717 -							if (gbFrameSkipCount >= framesToSkip || pauseAfterFrameAdvance)
  1.6718 -							{
  1.6719 -								gbRenderLine();
  1.6720 -								gbDrawSprites();
  1.6721 -
  1.6722 -								switch (systemColorDepth)
  1.6723 -								{
  1.6724 -								case 16:
  1.6725 -
  1.6726 -								{
  1.6727 -									u16 *dest = (u16 *)pix +
  1.6728 -									            (gbBorderLineSkip + 2) * (register_LY + gbBorderRowSkip + 1)
  1.6729 -									            + gbBorderColumnSkip;
  1.6730 -									for (int x = 0; x < 160; )
  1.6731 -									{
  1.6732 -										*dest++ = systemColorMap16[gbLineMix[x++]];
  1.6733 -										*dest++ = systemColorMap16[gbLineMix[x++]];
  1.6734 -										*dest++ = systemColorMap16[gbLineMix[x++]];
  1.6735 -										*dest++ = systemColorMap16[gbLineMix[x++]];
  1.6736 -
  1.6737 -										*dest++ = systemColorMap16[gbLineMix[x++]];
  1.6738 -										*dest++ = systemColorMap16[gbLineMix[x++]];
  1.6739 -										*dest++ = systemColorMap16[gbLineMix[x++]];
  1.6740 -										*dest++ = systemColorMap16[gbLineMix[x++]];
  1.6741 -
  1.6742 -										*dest++ = systemColorMap16[gbLineMix[x++]];
  1.6743 -										*dest++ = systemColorMap16[gbLineMix[x++]];
  1.6744 -										*dest++ = systemColorMap16[gbLineMix[x++]];
  1.6745 -										*dest++ = systemColorMap16[gbLineMix[x++]];
  1.6746 -
  1.6747 -										*dest++ = systemColorMap16[gbLineMix[x++]];
  1.6748 -										*dest++ = systemColorMap16[gbLineMix[x++]];
  1.6749 -										*dest++ = systemColorMap16[gbLineMix[x++]];
  1.6750 -										*dest++ = systemColorMap16[gbLineMix[x++]];
  1.6751 -									}
  1.6752 -									if (gbBorderOn)
  1.6753 -										dest += gbBorderColumnSkip;
  1.6754 -									*dest++ = 0;     // for filters that read one pixel more
  1.6755 -									break;
  1.6756 -								}
  1.6757 -								case 24:
  1.6758 -
  1.6759 -								{
  1.6760 -									u8 *dest = (u8 *)pix +
  1.6761 -									           3 * (gbBorderLineSkip * (register_LY + gbBorderRowSkip) +
  1.6762 -									                gbBorderColumnSkip);
  1.6763 -									for (int x = 0; x < 160; )
  1.6764 -									{
  1.6765 -										*((u32 *)dest) = systemColorMap32[gbLineMix[x++]];
  1.6766 -										dest += 3;
  1.6767 -										*((u32 *)dest) = systemColorMap32[gbLineMix[x++]];
  1.6768 -										dest += 3;
  1.6769 -										*((u32 *)dest) = systemColorMap32[gbLineMix[x++]];
  1.6770 -										dest += 3;
  1.6771 -										*((u32 *)dest) = systemColorMap32[gbLineMix[x++]];
  1.6772 -										dest += 3;
  1.6773 -
  1.6774 -										*((u32 *)dest) = systemColorMap32[gbLineMix[x++]];
  1.6775 -										dest += 3;
  1.6776 -										*((u32 *)dest) = systemColorMap32[gbLineMix[x++]];
  1.6777 -										dest += 3;
  1.6778 -										*((u32 *)dest) = systemColorMap32[gbLineMix[x++]];
  1.6779 -										dest += 3;
  1.6780 -										*((u32 *)dest) = systemColorMap32[gbLineMix[x++]];
  1.6781 -										dest += 3;
  1.6782 -
  1.6783 -										*((u32 *)dest) = systemColorMap32[gbLineMix[x++]];
  1.6784 -										dest += 3;
  1.6785 -										*((u32 *)dest) = systemColorMap32[gbLineMix[x++]];
  1.6786 -										dest += 3;
  1.6787 -										*((u32 *)dest) = systemColorMap32[gbLineMix[x++]];
  1.6788 -										dest += 3;
  1.6789 -										*((u32 *)dest) = systemColorMap32[gbLineMix[x++]];
  1.6790 -										dest += 3;
  1.6791 -
  1.6792 -										*((u32 *)dest) = systemColorMap32[gbLineMix[x++]];
  1.6793 -										dest += 3;
  1.6794 -										*((u32 *)dest) = systemColorMap32[gbLineMix[x++]];
  1.6795 -										dest += 3;
  1.6796 -										*((u32 *)dest) = systemColorMap32[gbLineMix[x++]];
  1.6797 -										dest += 3;
  1.6798 -										*((u32 *)dest) = systemColorMap32[gbLineMix[x++]];
  1.6799 -										dest += 3;
  1.6800 -									}
  1.6801 -									break;
  1.6802 -								}
  1.6803 -								case 32:
  1.6804 -
  1.6805 -								{
  1.6806 -									u32 *dest = (u32 *)pix +
  1.6807 -									            (gbBorderLineSkip + 1) * (register_LY + gbBorderRowSkip + 1)
  1.6808 -									            + gbBorderColumnSkip;
  1.6809 -									for (int x = 0; x < 160; )
  1.6810 -									{
  1.6811 -										*dest++ = systemColorMap32[gbLineMix[x++]];
  1.6812 -										*dest++ = systemColorMap32[gbLineMix[x++]];
  1.6813 -										*dest++ = systemColorMap32[gbLineMix[x++]];
  1.6814 -										*dest++ = systemColorMap32[gbLineMix[x++]];
  1.6815 -
  1.6816 -										*dest++ = systemColorMap32[gbLineMix[x++]];
  1.6817 -										*dest++ = systemColorMap32[gbLineMix[x++]];
  1.6818 -										*dest++ = systemColorMap32[gbLineMix[x++]];
  1.6819 -										*dest++ = systemColorMap32[gbLineMix[x++]];
  1.6820 -
  1.6821 -										*dest++ = systemColorMap32[gbLineMix[x++]];
  1.6822 -										*dest++ = systemColorMap32[gbLineMix[x++]];
  1.6823 -										*dest++ = systemColorMap32[gbLineMix[x++]];
  1.6824 -										*dest++ = systemColorMap32[gbLineMix[x++]];
  1.6825 -
  1.6826 -										*dest++ = systemColorMap32[gbLineMix[x++]];
  1.6827 -										*dest++ = systemColorMap32[gbLineMix[x++]];
  1.6828 -										*dest++ = systemColorMap32[gbLineMix[x++]];
  1.6829 -										*dest++ = systemColorMap32[gbLineMix[x++]];
  1.6830 -									}
  1.6831 -									break;
  1.6832 -								}
  1.6833 -								}
  1.6834 -							}
  1.6835 -						}
  1.6836 -					}
  1.6837 -					gbLcdTicks += GBLCD_MODE_0_CLOCK_TICKS;
  1.6838 -					gbLcdMode	= 0;
  1.6839 -					// only one LCD interrupt per line. may need to generalize...
  1.6840 -					if (!(register_STAT & 0x40) ||
  1.6841 -					    (register_LY != register_LYC))
  1.6842 -					{
  1.6843 -						if (register_STAT & 0x08)
  1.6844 -							gbInterrupt |= 2;
  1.6845 -					}
  1.6846 -					if (gbHdmaOn)
  1.6847 -					{
  1.6848 -						gbDoHdma();
  1.6849 -					}
  1.6850 -					break;
  1.6851 -				}
  1.6852 -				// mark the correct lcd mode on STAT register
  1.6853 -				register_STAT = (register_STAT & 0xfc) | gbLcdMode;
  1.6854 -			}
  1.6855 -		}
  1.6856 -
  1.6857 -		// serial emulation
  1.6858 -		if (gbSerialOn)
  1.6859 -		{
  1.6860 -#ifdef LINK_EMULATION
  1.6861 -			if (linkConnected)
  1.6862 -			{
  1.6863 -				gbSerialTicks -= clockTicks;
  1.6864 -
  1.6865 -				while (gbSerialTicks <= 0)
  1.6866 -				{
  1.6867 -					// increment number of shifted bits
  1.6868 -					gbSerialBits++;
  1.6869 -					linkProc();
  1.6870 -					if (gbSerialOn && (gbMemory[0xff02] & 1))
  1.6871 -					{
  1.6872 -						if (gbSerialBits == 8)
  1.6873 -						{
  1.6874 -							gbSerialBits	  = 0;
  1.6875 -							gbMemory[0xff01]  = 0xff;
  1.6876 -							gbMemory[0xff02] &= 0x7f;
  1.6877 -							gbSerialOn		  = 0;
  1.6878 -							gbInterrupt		 |= 8;
  1.6879 -							gbSerialTicks	  = 0;
  1.6880 -						}
  1.6881 -					}
  1.6882 -					gbSerialTicks += GBSERIAL_CLOCK_TICKS;
  1.6883 -				}
  1.6884 -			}
  1.6885 -			else
  1.6886 -			{
  1.6887 -#endif
  1.6888 -			if (gbMemory[0xff02] & 1)
  1.6889 -			{
  1.6890 -				gbSerialTicks -= clockTicks;
  1.6891 -
  1.6892 -				// overflow
  1.6893 -				while (gbSerialTicks <= 0)
  1.6894 -				{
  1.6895 -					// shift serial byte to right and put a 1 bit in its place
  1.6896 -					//      gbMemory[0xff01] = 0x80 | (gbMemory[0xff01]>>1);
  1.6897 -					// increment number of shifted bits
  1.6898 -					gbSerialBits++;
  1.6899 -					if (gbSerialBits == 8)
  1.6900 -					{
  1.6901 -						// end of transmission
  1.6902 -						if (gbSerialFunction)    // external device
  1.6903 -							gbMemory[0xff01] = gbSerialFunction(gbMemory[0xff01]);
  1.6904 -						else
  1.6905 -							gbMemory[0xff01] = 0xff;
  1.6906 -						gbSerialTicks	  = 0;
  1.6907 -						gbMemory[0xff02] &= 0x7f;
  1.6908 -						gbSerialOn		  = 0;
  1.6909 -						gbInterrupt		 |= 8;
  1.6910 -						gbSerialBits	  = 0;
  1.6911 -					}
  1.6912 -					else
  1.6913 -						gbSerialTicks += GBSERIAL_CLOCK_TICKS;
  1.6914 -				}
  1.6915 -			}
  1.6916 -#ifdef LINK_EMULATION
  1.6917 -		}
  1.6918 -#endif
  1.6919 -		}
  1.6920 -
  1.6921 -		// timer emulation
  1.6922 -		if (gbTimerOn)
  1.6923 -		{
  1.6924 -			gbTimerTicks -= clockTicks;
  1.6925 -
  1.6926 -			while (gbTimerTicks <= 0)
  1.6927 -			{
  1.6928 -				register_TIMA++;
  1.6929 -
  1.6930 -				if (register_TIMA == 0)
  1.6931 -				{
  1.6932 -					// timer overflow!
  1.6933 -
  1.6934 -					// reload timer modulo
  1.6935 -					register_TIMA = register_TMA;
  1.6936 -
  1.6937 -					// flag interrupt
  1.6938 -					gbInterrupt |= 4;
  1.6939 -				}
  1.6940 -
  1.6941 -				gbTimerTicks += gbTimerClockTicks;
  1.6942 -			}
  1.6943 -		}
  1.6944 -
  1.6945 -		/*
  1.6946 -		   if(soundOffFlag)
  1.6947 -		   {
  1.6948 -		   if(synchronize && !speedup)
  1.6949 -		   {
  1.6950 -		   synchronizeTicks -= clockTicks;
  1.6951 -
  1.6952 -		   while(synchronizeTicks < 0)
  1.6953 -		   {
  1.6954 -		   synchronizeTicks += SYNCHRONIZE_CLOCK_TICKS;
  1.6955 -
  1.6956 -		   DWORD now = timeGetTime();
  1.6957 -		   gbElapsedTime += (now - timeNow);
  1.6958 -
  1.6959 -		   if(gbElapsedTime < 50)
  1.6960 -		   {
  1.6961 -		   DWORD diff = 50 - gbElapsedTime;
  1.6962 -		   Sleep(diff);
  1.6963 -		   timeNow = timeGetTime();
  1.6964 -		   elapsedTime = timeNow - now - diff;
  1.6965 -		   if((int)elapsedTime < 0)
  1.6966 -		   elapsedTime = 0;
  1.6967 -		   } else
  1.6968 -		   {
  1.6969 -		   timeNow = timeGetTime();
  1.6970 -		   elapsedTime = 0;
  1.6971 -		   }
  1.6972 -		   }
  1.6973 -		   }
  1.6974 -		   }
  1.6975 -		 */
  1.6976 -
  1.6977 -		soundTicks -= clockTicks;
  1.6978 -		while (soundTicks < 0) // must be < 1 when soundtick_t is real data type
  1.6979 -		{
  1.6980 -			soundTicks += SOUND_CLOCK_TICKS;
  1.6981 -
  1.6982 -			gbSoundTick();
  1.6983 -		}
  1.6984 -
  1.6985 -		register_IF = gbInterrupt;
  1.6986 -
  1.6987 -		if (IFF & 0x20)
  1.6988 -		{
  1.6989 -			IFF &= 0xdf;
  1.6990 -			IFF |= 0x01;
  1.6991 -			gbInterruptWait = 0;
  1.6992 -		}
  1.6993 -		else if (gbInterrupt)
  1.6994 -		{
  1.6995 -			if (gbInterruptWait == 0)
  1.6996 -			{
  1.6997 -				//        gbInterruptWait = 0;
  1.6998 -
  1.6999 -				if (IFF & 0x01)
  1.7000 -				{
  1.7001 -					if ((gbInterrupt & 1) && (register_IE & 1))
  1.7002 -					{
  1.7003 -						gbVblank_interrupt();
  1.7004 -						continue;
  1.7005 -					}
  1.7006 -
  1.7007 -					if ((gbInterrupt & 2) && (register_IE & 2))
  1.7008 -					{
  1.7009 -						gbLcd_interrupt();
  1.7010 -						continue;
  1.7011 -					}
  1.7012 -
  1.7013 -					if ((gbInterrupt & 4) && (register_IE & 4))
  1.7014 -					{
  1.7015 -						gbTimer_interrupt();
  1.7016 -						continue;
  1.7017 -					}
  1.7018 -
  1.7019 -					if ((gbInterrupt & 8) && (register_IE & 8))
  1.7020 -					{
  1.7021 -						gbSerial_interrupt();
  1.7022 -						continue;
  1.7023 -					}
  1.7024 -
  1.7025 -					if ((gbInterrupt & 16) && (register_IE & 16))
  1.7026 -					{
  1.7027 -						gbJoypad_interrupt();
  1.7028 -						continue;
  1.7029 -					}
  1.7030 -				}
  1.7031 -			}
  1.7032 -			else
  1.7033 -			{
  1.7034 -				gbInterruptWait -= clockTicks;
  1.7035 -				if (gbInterruptWait < 0)
  1.7036 -					gbInterruptWait = 0;
  1.7037 -			}
  1.7038 -		}
  1.7039 -
  1.7040 -		if (useOldFrameTiming)
  1.7041 -		{
  1.7042 -			// old timing code
  1.7043 -			if (ticksToStop > 0)
  1.7044 -				continue;
  1.7045 -		}
  1.7046 -		else
  1.7047 -		{
  1.7048 -			if (!newFrame && (register_LCDC & 0x80) != 0)
  1.7049 -				continue;
  1.7050 -		}
  1.7051 -
  1.7052 -		if (!(register_LCDC & 0x80))
  1.7053 -		{
  1.7054 -			if (!useOldFrameTiming)
  1.7055 -			{
  1.7056 -				// FIXME: since register_LY can be reset to 0 by some games, frame length is variable
  1.7057 -				// and infinite loops can occurr
  1.7058 -				// for now, it IS necessary to do something on this condition or games like
  1.7059 -				// Megaman would freeze upon low-level restart interrupt sequence (Start+Select+A+B).
  1.7060 -				// the only sensible way to fix this issue is to implement the RIGHT frame timing
  1.7061 -#ifdef WANTS_INCOMPLETE_WORKAROUND
  1.7062 -				if (systemReadJoypads())
  1.7063 -				{
  1.7064 -					if (gbSgbMode && gbSgbMultiplayer)
  1.7065 -					{
  1.7066 -						if (gbSgbFourPlayers)
  1.7067 -						{
  1.7068 -							gbJoymask[0] = systemGetJoypad(0, false);
  1.7069 -							gbJoymask[1] = systemGetJoypad(1, false);
  1.7070 -							gbJoymask[2] = systemGetJoypad(2, false);
  1.7071 -							gbJoymask[3] = systemGetJoypad(3, false);
  1.7072 -						}
  1.7073 -						else
  1.7074 -						{
  1.7075 -							gbJoymask[0] = systemGetJoypad(0, false);
  1.7076 -							gbJoymask[1] = systemGetJoypad(1, false);
  1.7077 -						}
  1.7078 -					}
  1.7079 -					else
  1.7080 -					{
  1.7081 -						gbJoymask[0] = systemGetJoypad(0, false);
  1.7082 -					}
  1.7083 -				}
  1.7084 -				else
  1.7085 -					gbJoymask[0] = gbJoymask[1] = gbJoymask[2] = gbJoymask[3] = 0;
  1.7086 +	      else
  1.7087 +		gbJoymask[0] = gbJoymask[1] = gbJoymask[2] = gbJoymask[3] = 0;
  1.7088  #else
  1.7089  #endif
  1.7090 -			}
  1.7091 -		}
  1.7092 -
  1.7093 -		// makes sure frames are really divided across input sampling boundaries which occur at a constant rate
  1.7094 -		if (newFrame || useOldFrameTiming)
  1.7095 -		{
  1.7096 -///			extern void VBAOnEnteringFrameBoundary();
  1.7097 -///			VBAOnEnteringFrameBoundary();
  1.7098 -
  1.7099 -			break;
  1.7100 -		}
  1.7101 +	    }
  1.7102  	}
  1.7103 +
  1.7104 +      // makes sure frames are really divided across input sampling boundaries which occur at a constant rate
  1.7105 +      if (newFrame || useOldFrameTiming)
  1.7106 +	{
  1.7107 +	  ///			extern void VBAOnEnteringFrameBoundary();
  1.7108 +	  ///			VBAOnEnteringFrameBoundary();
  1.7109 +
  1.7110 +	  break;
  1.7111 +	}
  1.7112 +    }
  1.7113  }
  1.7114  
  1.7115  struct EmulatedSystem GBSystem =
  1.7116 -{
  1.7117 -	// emuMain
  1.7118 -	gbEmulate,
  1.7119 -	// emuReset
  1.7120 -	gbReset,
  1.7121 -	// emuCleanUp
  1.7122 -	gbCleanUp,
  1.7123 -	// emuReadBattery
  1.7124 -	gbReadBatteryFile,
  1.7125 -	// emuWriteBattery
  1.7126 -	gbWriteBatteryFile,
  1.7127 -	// emuReadBatteryFromStream
  1.7128 -	gbReadBatteryFromStream,
  1.7129 -	// emuWriteBatteryToStream
  1.7130 -	gbWriteBatteryToStream,
  1.7131 -	// emuReadState
  1.7132 -	gbReadSaveState,
  1.7133 -	// emuWriteState
  1.7134 -	gbWriteSaveState,
  1.7135 -	// emuReadStateFromStream
  1.7136 -	gbReadSaveStateFromStream,
  1.7137 -	// emuWriteStateToStream
  1.7138 -	gbWriteSaveStateToStream,
  1.7139 -	// emuReadMemState
  1.7140 -	gbReadMemSaveState,
  1.7141 -	// emuWriteMemState
  1.7142 -	gbWriteMemSaveState,
  1.7143 -	// emuWritePNG
  1.7144 -	gbWritePNGFile,
  1.7145 -	// emuWriteBMP
  1.7146 -	gbWriteBMPFile,
  1.7147 -	// emuUpdateCPSR
  1.7148 -	NULL,
  1.7149 -	// emuHasDebugger
  1.7150 -	false,
  1.7151 -	// emuCount
  1.7152 +  {
  1.7153 +    // emuMain
  1.7154 +    gbEmulate,
  1.7155 +    // emuReset
  1.7156 +    gbReset,
  1.7157 +    // emuCleanUp
  1.7158 +    gbCleanUp,
  1.7159 +    // emuReadBattery
  1.7160 +    gbReadBatteryFile,
  1.7161 +    // emuWriteBattery
  1.7162 +    gbWriteBatteryFile,
  1.7163 +    // emuReadBatteryFromStream
  1.7164 +    gbReadBatteryFromStream,
  1.7165 +    // emuWriteBatteryToStream
  1.7166 +    gbWriteBatteryToStream,
  1.7167 +    // emuReadState
  1.7168 +    gbReadSaveState,
  1.7169 +    // emuWriteState
  1.7170 +    gbWriteSaveState,
  1.7171 +    // emuReadStateFromStream
  1.7172 +    gbReadSaveStateFromStream,
  1.7173 +    // emuWriteStateToStream
  1.7174 +    gbWriteSaveStateToStream,
  1.7175 +    // emuReadMemState
  1.7176 +    gbReadMemSaveState,
  1.7177 +    // emuWriteMemState
  1.7178 +    gbWriteMemSaveState,
  1.7179 +    // emuWritePNG
  1.7180 +    gbWritePNGFile,
  1.7181 +    // emuWriteBMP
  1.7182 +    gbWriteBMPFile,
  1.7183 +    // emuUpdateCPSR
  1.7184 +    NULL,
  1.7185 +    // emuHasDebugger
  1.7186 +    false,
  1.7187 +    // emuCount
  1.7188  #ifdef FINAL_VERSION
  1.7189 -	70000 / 4,
  1.7190 +    70000 / 4,
  1.7191  #else
  1.7192 -	1000,
  1.7193 +    1000,
  1.7194  #endif
  1.7195 -};
  1.7196 +  };
  1.7197  
  1.7198  // is there a reason to use more than one set of counters?
  1.7199  EmulatedSystemCounters &GBSystemCounters = systemCounters;
  1.7200  
  1.7201  /*
  1.7202 -   EmulatedSystemCounters GBSystemCounters =
  1.7203 -   {
  1.7204 -    // frameCount
  1.7205 -    0,
  1.7206 -    // lagCount
  1.7207 -    0,
  1.7208 -    // lagged
  1.7209 -    true,
  1.7210 -    // laggedLast
  1.7211 -    true,
  1.7212 -   };
  1.7213 - */
  1.7214 +  EmulatedSystemCounters GBSystemCounters =
  1.7215 +  {
  1.7216 +  // frameCount
  1.7217 +  0,
  1.7218 +  // lagCount
  1.7219 +  0,
  1.7220 +  // lagged
  1.7221 +  true,
  1.7222 +  // laggedLast
  1.7223 +  true,
  1.7224 +  };
  1.7225 +*/