1
2 /*
3
4 gameboy.c
5
6 This file emulates the hardware (all around the Gameboy-CPU).
7
8 */
9
10
11 #include <stdio.h>
12 #include <stdlib.h>
13
14 #ifdef UNIX
15 #include <unistd.h>
16 #endif
17
18 #include <ctype.h>
19 #include <string.h>
20
21 #include "globals.h"
22 #include "gameboy.h"
23 #include "sgb.h"
24 #include "z80.h"
25
26 #define Z80OPC_GAMEBOYC_SKIP /* only M_RST needed from here */
27 #include "z80opc.h"
28
29 #include "arplay.h"
30
31 #include "sys.h"
32
33 #ifdef SOUND
34 /*#define DEBUG_SOUND*/
35 #include "sound.h"
36 #endif
37
38 rombank bank[GB_MAXROMBANKCOUNT]; /* rom */
39 rambank sram[GB_MAXRAMBANKCOUNT]; /* sram */
40 uchar *vram[2]; /* vram */
41 uchar *iram[8]; /* internal ram */
42 /* don't forget echoing ! */
43 uchar *oam; /* oam */
44 uchar *io; /* io */
45
46
47 char *lcdbuffer; /* gameboy screen buffer */
48 unsigned int GB_BGPAL[8][4]=
49 {{0x7FFF,0x56B5,0x294A,0x0000},
50 {0x7FFF,0x56B5,0x294A,0x0000},
51 {0x7FFF,0x56B5,0x294A,0x0000},
52 {0x7FFF,0x56B5,0x294A,0x0000},
53 {0x7FFF,0x56B5,0x294A,0x0000},
54 {0x7FFF,0x56B5,0x294A,0x0000},
55 {0x7FFF,0x56B5,0x294A,0x0000},
56 {0x7FFF,0x56B5,0x294A,0x0000}};
57 unsigned int GB_OBJPAL[8][4]=
58 {{0x7FFF,0x56B5,0x294A,0x0000},
59 {0x7FFF,0x56B5,0x294A,0x0000},
60 {0x7FFF,0x56B5,0x294A,0x0000},
61 {0x7FFF,0x56B5,0x294A,0x0000},
62 {0x7FFF,0x56B5,0x294A,0x0000},
63 {0x7FFF,0x56B5,0x294A,0x0000},
64 {0x7FFF,0x56B5,0x294A,0x0000},
65 {0x7FFF,0x56B5,0x294A,0x0000}};
66
67 ulong BGPAL[8][4],OBJPAL[8][4];
68
69 uint rombanknr,workbanknr;
70 uint romselectmask;
71 uchar rambanknr;
72 int rambankenabled;
73 uchar sramselectmask;
74 int mbctype;
75 int mbcmode;
76 uchar newjoypadstate,joypadstate,lcdphase;
77 int timerfreq,timerclks,dividerclks,lcdclks,joypadclks,
78 vblankdelay,sramsize,srambanksize,lastjoysel,serialioclks,
79 soundcounter,ABORT_EMULATION,vblankoccured,
80 hdmastarted,hdmasrc,hdmadst,soundclks,snd_updateclks,colormode,
81 siosendout;
82
83 int serialclks[2][2]={{4096,2048},{128,64}};
84 /* [SC bit 1][cpuspeed] */
85
86 char sramfile[256];
87
88 void (*scanline)(void); /* standard gameboy video output */
89 void gb_scanline8(void);
90 void gb_scanline16(void);
91 void gb_scanline32(void);
92
93 void cgb_scanline16(void); /* gameboy color video output */
94 void cgb_scanline32(void);
95 void cgb_scanline8(void);
96
97 void switch2color(void);
98
99 int GB_SRAMBANKSIZE[]=
100 {
101 0x2000,0x0800,0x2000,0x2000
102 };
103 uchar GB_SRAMSELECTMASK[]=
104 {
105 1,1,1,3
106 };
107 uchar GB_SRAMBANKCOUNT[]=
108 {
109 1,1,1,4
110 };
111
112 uint GB_VCLKS[]=
113 {
114 80,172,208,560
115 };
116 /*uint GB_VCLKS[]=
117 {
118 80,172,208,460 * cycles 2,3,0,sigma *
119 };*/
120 /*uint GB_VCLKS[]=
121 {
122 80,172,204,456 * cycles 2,3,0,sigma (old, I made the refresh slower) *
123 };*/
124
125 uint GB_TIMERFRQ[]=
126 {
127 1024,16,64,256
128 };
129
130 uchar Area_0xFF00_init[]=
131 {
132 0xCF,0x00,0x7E,0xFF,0xAD,0x00,0x00,0xF8,
133 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE1,
134 0x80,0xBF,0xF3,0xFF,0x3F,0xFF,0x3F,0x00,
135 0xFF,0x3F,0x7F,0xFF,0x9F,0xFF,0x3F,0xFF,
136 0xFF,0x00,0x00,0x3F,0x77,0xF3,0xF1,0x00,
137 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
138 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
139 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
140 0x91,0x80,0x00,0x00,0x05,0x00,0x00,0xFC,
141 0xFC,0xFC,0x00,0x00,0x00,0x00,0x00,0x00
142 };
143
144 uchar Nintendo_Logo[]=
145 {
146 0xCE,0xED,0x66,0x66,0xCC,0x0D,0x00,0x0B,
147 0x03,0x73,0x00,0x83,0x00,0x0C,0x00,0x0D,
148 0x00,0x08,0x11,0x1F,0x88,0x89,0x00,0x0E,
149 0xDC,0xCC,0x6E,0xE6,0xDD,0xDD,0xD9,0x99,
150 0xBB,0xBB,0x67,0x63,0x6E,0x0E,0xEC,0xCC,
151 0xDD,0xDC,0x99,0x9F,0xBB,0xB9,0x33,0x3E
152 };
153
154 uchar H_Flip[]=
155 {
156 0x00,0x80,0x40,0xC0,0x20,0xA0,0x60,0xE0,
157 0x10,0x90,0x50,0xD0,0x30,0xB0,0x70,0xF0,
158 0x08,0x88,0x48,0xC8,0x28,0xA8,0x68,0xE8,
159 0x18,0x98,0x58,0xD8,0x38,0xB8,0x78,0xF8,
160 0x04,0x84,0x44,0xC4,0x24,0xA4,0x64,0xE4,
161 0x14,0x94,0x54,0xD4,0x34,0xB4,0x74,0xF4,
162 0x0C,0x8C,0x4C,0xCC,0x2C,0xAC,0x6C,0xEC,
163 0x1C,0x9C,0x5C,0xDC,0x3C,0xBC,0x7C,0xFC,
164 0x02,0x82,0x42,0xC2,0x22,0xA2,0x62,0xE2,
165 0x12,0x92,0x52,0xD2,0x32,0xB2,0x72,0xF2,
166 0x0A,0x8A,0x4A,0xCA,0x2A,0xAA,0x6A,0xEA,
167 0x1A,0x9A,0x5A,0xDA,0x3A,0xBA,0x7A,0xFA,
168 0x06,0x86,0x46,0xC6,0x26,0xA6,0x66,0xE6,
169 0x16,0x96,0x56,0xD6,0x36,0xB6,0x76,0xF6,
170 0x0E,0x8E,0x4E,0xCE,0x2E,0xAE,0x6E,0xEE,
171 0x1E,0x9E,0x5E,0xDE,0x3E,0xBE,0x7E,0xFE,
172 0x01,0x81,0x41,0xC1,0x21,0xA1,0x61,0xE1,
173 0x11,0x91,0x51,0xD1,0x31,0xB1,0x71,0xF1,
174 0x09,0x89,0x49,0xC9,0x29,0xA9,0x69,0xE9,
175 0x19,0x99,0x59,0xD9,0x39,0xB9,0x79,0xF9,
176 0x05,0x85,0x45,0xC5,0x25,0xA5,0x65,0xE5,
177 0x15,0x95,0x55,0xD5,0x35,0xB5,0x75,0xF5,
178 0x0D,0x8D,0x4D,0xCD,0x2D,0xAD,0x6D,0xED,
179 0x1D,0x9D,0x5D,0xDD,0x3D,0xBD,0x7D,0xFD,
180 0x03,0x83,0x43,0xC3,0x23,0xA3,0x63,0xE3,
181 0x13,0x93,0x53,0xD3,0x33,0xB3,0x73,0xF3,
182 0x0B,0x8B,0x4B,0xCB,0x2B,0xAB,0x6B,0xEB,
183 0x1B,0x9B,0x5B,0xDB,0x3B,0xBB,0x7B,0xFB,
184 0x07,0x87,0x47,0xC7,0x27,0xA7,0x67,0xE7,
185 0x17,0x97,0x57,0xD7,0x37,0xB7,0x77,0xF7,
186 0x0F,0x8F,0x4F,0xCF,0x2F,0xAF,0x6F,0xEF,
187 0x1F,0x9F,0x5F,0xDF,0x3F,0xBF,0x7F,0xFF,
188 };
189
190 uchar IOIn(uint);
191 void IOOut(uint,uchar);
192
193
IOIn(uint addr)194 uchar IOIn(uint addr)
195 {
196 switch (addr) {
197 case 0x44:
198 return LY<153 ? LY : 0;
199
200 default:
201 return io[addr];
202 }
203 }
204
GetByteAt(uint addr)205 uchar GetByteAt(uint addr)
206 {
207 #ifdef HARDDEBUG
208 if (addr>=0xFF10&&addr<=0xFF27) {
209 fprintf(OUTSTREAM,"IO read access: 0x%04X: %04X=>",Z80_REG.W.PC,addr);
210 if (addr>=0x4000) {
211 if (addr>=0x8000) {
212 if (addr>=0xA000) {
213 if (addr>=0xC000) {
214 if (addr>=0xD000) {
215 if (addr>=0xE000) {
216 if (addr>=0xF000) {
217 if (addr>=0xFE00) {
218 if (addr>=0xFF00) {
219 fprintf(OUTSTREAM,"%02X",IOIn(addr&0x00FF));
220 } else fprintf(OUTSTREAM,"%02X",oam[addr&0x00FF]);
221 } else fprintf(OUTSTREAM,"%02X",
222 iram[workbanknr][addr&0x0FFF]);
223 } else fprintf(OUTSTREAM,"%02X",iram[0][addr&0x0FFF]);
224 } else fprintf(OUTSTREAM,"%02X",
225 iram[workbanknr][addr&0x0FFF]);
226 } else fprintf(OUTSTREAM,"%02X",iram[0][addr&0x0FFF]);
227 } else fprintf(OUTSTREAM,"%02X",sram[rambanknr][addr&0x1FFF]);
228 } else fprintf(OUTSTREAM,"%02X",vram[VBK&1][addr&0x1FFF]);
229 } else fprintf(OUTSTREAM,"%02X",bank[rombanknr][addr&0x3FFF]);
230 } else fprintf(OUTSTREAM,"%02X",bank[0][addr]);
231 fprintf(OUTSTREAM,"\n");
232 }
233 #endif
234 if (addr<0x4000) return bank[0][addr];
235 if (addr<0x8000) return bank[rombanknr][addr & 0x3FFF];
236 if (addr<0xA000) return vram[VBK&1][addr & 0x1FFF];
237 if (addr<0xC000)
238 return /*(addr&0x1FFF)>=srambanksize ? 0 :*/
239 sram[rambanknr][addr & 0x1FFF];
240 if (addr<0xD000) return iram[0][addr&0x0FFF];
241 if (addr<0xE000) return iram[workbanknr][addr&0x0FFF];
242 if (addr<0xF000) return iram[0][addr&0x0FFF];
243 if (addr<0xFE00) return iram[workbanknr][addr&0x0FFF];
244 if (addr<0xFF00) return oam[addr & 0x00FF];
245 return IOIn(addr & 0x00FF);
246
247 /* switch (addr >> 13) {
248
249 }*/
250 }
251
GetWordAt(uint addr)252 uint GetWordAt(uint addr)
253 {
254 return ((uint)GetByteAt(addr+1)<<8)|GetByteAt(addr);
255 }
256
IOOut(uint addr,uchar value)257 void IOOut(uint addr,uchar value)
258 {
259 int i;
260 uint u;
261
262 value=ar_checkwrite(addr+0xFF00,value);
263 if (addr<0x4C) {
264 switch (addr) {
265 case 0x00: /* joypad info */
266 if (sgb_packagetransfer && !colormode) {
267 switch ((value >> 4)& 0x03) {
268 case 0:
269 #ifdef TDEBUG
270 fprintf(OUTSTREAM,"init\n");
271 sgb_dumppackagebuffer();
272 #endif
273 sgb_packagetransfer=1;
274 sgb_byte&=0xFFF0;
275 /* sgb_buffer[0]=0;*/
276 sgb_bitnr=0;
277 sgb_bit=-1;
278 break;
279 case 1:sgb_bit=1;break;
280 case 2:sgb_bit=0;break;
281 case 3:
282 if (sgb_bit<0) break;
283 if ((sgb_pkgdone==0)&&(sgb_byte<SGB_BUFFERSIZE)) {
284 sgb_buffer[sgb_byte]|=(sgb_bit<<sgb_bitnr);
285 sgb_bitnr++;
286 if (sgb_bitnr>7) {
287 sgb_bitnr=0;
288 sgb_byte++;
289 sgb_buffer[sgb_byte]=0;
290
291 /* printf("(%d,%d)\n",sgb_byte,sgb_bitnr);*/
292 if (!(sgb_byte&0x0F)) {
293 sgb_packagetransfer=0;
294 sgb_pkgdone=1;
295 sgb_processcmd();
296 }
297 }
298 } else {
299 /* package transfer successfully closed */
300
301 sgb_closecmd();
302 }
303 break;
304 }
305 }
306
307 switch ((value >> 4)& 0x03) {
308 case 0:
309 #ifdef TDEBUG
310 fprintf(OUTSTREAM,"init\n");
311 sgb_dumppackagebuffer();
312 #endif
313 sgb_packagetransfer=1;
314 sgb_pkgdone=0;
315 sgb_byte&=0xFFF0;
316 sgb_bitnr=0;
317 /* sgb_buffer[0]=0;*/
318 sgb_bit=-1;
319 break;
320 case 1:lastjoysel=0;break;
321 case 2:lastjoysel=1;break;
322 case 3:lastjoysel=2;sgb_packagetransfer=0;break;
323 }
324 switch (lastjoysel) {
325 case 0:
326 P1=(joypadstate&0x0F)|0xD0;
327 break;
328 case 1:
329 P1=(joypadstate>>4)|0xE0;
330 break;
331 case 2:
332 /*if (!force_stdgameboy) P1=0x02;*/
333 break;
334 }
335 /*printf("jps: (%02X,%02X,%d)->%02X\n",value,joypadstate,lastjoysel,P1);*/
336 break;
337 case 0x01: /* serial read/write byte */
338 siosendout=value;
339 break;
340 case 0x02: /* serial control */
341 if (colormode)
342 serialioclks=serialclks[(SC&2)>>1][DBLSPEED];
343 else serialioclks=serialclks[0][0];
344 #ifdef DIALOGLINK
345 if ((value&0x81)==0x81) {
346 dlglink_sndbyte(siosendout);
347 #ifdef HARDDEBUG
348 printf("Master sio at PC:%04X (CTRL:%02X) =>%02X.\n",
349 Z80_REG.W.PC,value,siosendout);
350 #endif
351 }
352 #ifdef HARDDEBUG
353 if ((value&0x81)==0x80) {
354 printf("Slave sio at PC:%04X (CTRL:%02X) =>%02X.\n",
355 Z80_REG.W.PC,value,siosendout);
356 }
357 #endif
358 #endif
359
360 SC=value;
361 #ifndef DIALOGLINK
362 if (SC&0x01) IF|=0x08;
363 SC&=0x7F;SB=0xFF;
364 #endif
365 break;
366 case 0x04: /* reset divider reg */
367 DIV=0;dividerclks=GB_DIVLOAD;
368 break;
369 case 0x07:
370 TAC=value|0xF8;
371 timerclks=timerfreq=GB_TIMERFRQ[value&0x03];
372 break;
373 case 0x0F: /* interrupt flag */
374 IF=value|0xE0;
375 break;
376 case 0x40: /* lcd control */
377 if ((value & 0x80)==0) {
378 LY=0;
379 lcdphase=0;
380 STAT=(STAT&0xFC)|2;
381 lcdclks=GB_VCLKS[0];
382 }
383 LCDC=value;
384 break;
385 case 0x41:
386 STAT=(STAT&0x07)|0x80|(value&0x78);
387 break;
388 case 0x44:
389 /* should I reset ? */
390 break;
391 case 0x46:
392 for (i=0;i<0xA0;i++)
393 /* if ((i&3)==3)
394 oam[i]=(oam[i]&0x0F)|(GetByteAt(((uint)value << 8)+i)&0xF0);
395 else */
396 oam[i]=GetByteAt(((uint)value << 8)+i);
397 break;
398
399 /* unsupported regs (unchanged) */
400 case 0x03:
401
402 /* sound control regs */
403 case 0x15:
404 io[addr]=value;
405 break;
406 case 0x24: /* handled in sound module */
407 case 0x25:
408 case 0x26:
409 if (addr==0xFF26 && (value&0x80)>0) {
410 soundcounter=4000000;
411 io[0x26]=0x8F;
412 }
413
414 #ifdef DEBUG_SOUND
415 printf("NR5%d<=%02X\n",(addr-4)&0x7,value);
416 #endif
417
418 io[addr]=value;
419 break;
420
421 case 0x10:
422 NR10=value;
423 #ifdef SOUND
424 #ifdef DEBUG_SOUND
425 if (value&7) printf("NR10<=%02X\n",value);
426 #endif
427 snd1_st=snd1_str=((NR10>>4)&7)<<1;
428 #endif
429 break;
430 case 0x11:
431 NR11=value;
432 #ifdef DEBUG_SOUND
433 if ((value&0xC0)!=0x80) printf("NR11<=%02X\n",value);
434 #endif
435 break;
436 case 0x12:
437 NR12=value;
438 #ifdef DEBUG_SOUND
439 printf("NR12<=%02X\n",value);
440 #endif
441 #ifdef SOUND
442 value=(value&7)<<2;
443 if (/*(NR12&8)==0 &&*/ value<snd_length1) snd_length1=value;
444 #endif
445 break;
446 case 0x13:
447 NR13=value;
448 #ifdef SOUND
449 /* if (value==0xFF) snd_length1=0;*/
450 snd_reload1=gbfreq((((int)(NR14&7)<<8))|NR13);
451 #endif
452 #ifdef DEBUG_SOUND
453 printf("snd_reload1(low: %05i;%02X-%02X)\n",snd_reload1,NR13,NR12);
454 #endif
455 break;
456 case 0x14:
457 NR14=value;
458 #ifdef SOUND
459 snd_reload1=gbfreq((((int)(NR14&7)<<8))|NR13);
460 if (value&0x80) {
461 if ((snd_init1=NR12&0xF7 ? 1 : 0))
462 snd_length1=value & 0x40 ? 65-(NR11&0x3F) : 0xFFFF;
463 #ifdef DEBUG_SOUND
464 printf("%05i %09i (%02X%02X)\n",
465 ((int)(NR14&7)<<8)|NR13,snd_reload1,NR13,NR14);
466 #endif
467 }
468 #endif
469 break;
470
471 case 0x16:
472 #ifdef DEBUG_SOUND
473 if ((value&0xC0)!=0x80) printf("NR21<=%02X\n",value);
474 #endif
475 NR21=value;
476 break;
477 case 0x17:
478 NR22=value;
479 #ifdef SOUND
480 value=(value&7)<<2;
481 if (/*(NR22&8)==0 &&*/ value<snd_length2) snd_length2=value;
482 #endif
483 break;
484 case 0x18:
485 NR23=value;
486 #ifdef SOUND
487 if (value==0xFF) snd_length2=0;
488 snd_reload2=gbfreq((((int)(NR24&7)<<8))|NR23);
489 #endif
490 break;
491 case 0x19:
492 NR24=value;
493 #ifdef SOUND
494 snd_reload2=gbfreq((((int)(NR24&7)<<8))|NR23);
495 if (value&0x80) {
496 if ((snd_init2=NR22&0xF7 ? 1 : 0))
497 snd_length2=value & 0x40 ? 65-(NR21&0x3F) : 0xFFFF;
498 }
499 #endif
500 break;
501
502 case 0x1A:
503 NR30=value;
504 break;
505 case 0x1B:
506 NR31=value;
507 break;
508 case 0x1C:
509 NR32=value;
510 #ifdef SOUND
511 switch ((value>>5)&3) {
512 case 0:snd_shr=4;break;
513 case 1:snd_shr=0;break;
514 case 2:snd_shr=1;break;
515 case 3:snd_shr=2;break;
516 }
517 #endif
518 break;
519 case 0x1D:
520 NR33=value;
521 #ifdef SOUND
522 if (value==0xFF) snd_length3=0;
523 snd_reload3=gbfreq((((int)(NR34&7)<<8))|NR33)>>1;
524 #endif
525 break;
526 case 0x1E:
527 NR34=value;
528 #ifdef SOUND
529 snd_reload3=gbfreq((((int)(NR34&7)<<8))|NR33)>>1;
530 if (value&0x80) {
531 if ((snd_init3=(NR30>>7)))
532 snd_length3=value & 0x40 ? 257-NR31 : 0xFFFF;
533 }
534 #endif
535 break;
536
537 case 0x20:
538 #ifdef DEBUG_SOUND
539 printf("NR41<=%02X\n",value);
540 #endif
541 NR41=value;
542 break;
543 case 0x21:
544 #ifdef DEBUG_SOUND
545 printf("NR42<=%02X\n",value);
546 #endif
547 NR42=value;
548 #ifdef SOUND
549 value=(value&7)<<2;
550 if (/*(NR42&8)==0 &&*/ value<snd_length4) snd_length4=value;
551 /* if ((NR42&0xF7)==0) snd_init4=snd_length4=0;*/
552 #endif
553 break;
554 case 0x22:
555 #ifdef DEBUG_SOUND
556 printf("NR43<=%02X\n",value);
557 #endif
558 NR43=value;
559 break;
560 case 0x23:
561 #ifdef DEBUG_SOUND
562 printf("NR44<=%02X\n",value);
563 #endif
564 NR44=value;
565 /*
566 #ifdef SOUND
567 if (value&0x80) {
568 snd_reload4=1;
569 if ((snd_init4=NR42&0xF8 ? 1 : 0)) {
570 snd_length4=value & 0x40 ? 64-(NR41&0x3F) :
571 (NR42 & 0x07)<<4;
572 printf("snd_len4 %d\n",snd_length4);
573 }
574 }
575 #endif
576 */
577 #ifdef SOUND
578 if (value&0x80) {
579 snd_reload4=1;
580 if ((snd_init4=NR42&0xF7 ? NR44>>7 : 0))
581 snd_length4=value & 0x40 ? 65-(NR41&0x3F) :
582 (NR42 & 0x07)<<4;
583 }
584 #endif
585 soundcounter=4000000;
586 break;
587
588
589
590 /* unchanged writes */
591 case 0x05: /* timer counter */
592 case 0x06: /* timer modulo */
593 case 0x30: /* waveform sound data */
594 case 0x31: /**/
595 case 0x32:
596 case 0x33:
597 case 0x34: /**/
598 case 0x35:
599 case 0x36:
600 case 0x37: /**/
601 case 0x38:
602 case 0x39:
603 case 0x3A:
604 case 0x3B:
605 case 0x3C: /**/
606 case 0x3D:
607 case 0x3E:
608 case 0x3F: /* --- waveform end */
609 case 0x42: /* scroll y */
610 case 0x43: /* scroll x */
611 case 0x45: /* lcd y compare */
612 case 0x47: /* BG palette */
613 case 0x48: /* sprite palette 0 */
614 case 0x49: /* sprite palette 1 */
615 case 0x4A: /* window y */
616 case 0x4B: /* window x */
617 io[addr]=value;
618 break;
619 default:
620 return;
621 }
622 } else {
623 /* also 0xFFFF (=interrupt enable) *** unchanged *** */
624 if (addr>0x7F) io[addr]=value;
625
626 /* CGB io handling */
627 switch (addr) {
628 case 0x4D: /* cpu speed switch */
629 if (!colormode) switch2color();
630 KEY1=(KEY1&0x80)|(value&1);
631 break;
632 case 0x4F: /* video bank selection */
633 if (!colormode) switch2color();
634 VBK=value&1;
635 break;
636 case 0x51: /* cgb DMA source hi */
637 if (!colormode) switch2color();
638 HDMA1=value;
639 hdmasrc=((unsigned int)HDMA1<<8)|(HDMA2&0xF0);
640 break;
641 case 0x52: /* cgb DMA source low */
642 if (!colormode) switch2color();
643 HDMA2=value&0xF0;
644 hdmasrc=((unsigned int)HDMA1<<8)|(HDMA2&0xF0);
645 break;
646 case 0x53: /* cgb DMA destination hi */
647 if (!colormode) switch2color();
648 HDMA3=value&0x1F;
649 hdmadst=((unsigned int)(HDMA3&0x1F)<<8)|(HDMA4&0xF0);
650 break;
651 case 0x54: /* cgb DMA destination low */
652 if (!colormode) switch2color();
653 HDMA4=value&0xF0;
654 hdmadst=((unsigned int)(HDMA3&0x1F)<<8)|(HDMA4&0xF0);
655 break;
656 case 0x55: /* cgb DMA start and counter */
657 if (!colormode) switch2color();
658 HDMA5=value;
659 hdmasrc=((unsigned int)HDMA1<<8)|(HDMA2&0xF0);
660 hdmadst=((unsigned int)(HDMA3&0x1F)<<8)|(HDMA4&0xF0);
661 switch (hdmastarted) { /* general=>1; horizontal=>2 stoping=>-1*/
662 case 2:
663 hdmastarted=value&0x80 ? 2 : -1;
664 HDMA5&=0x7F;
665 break;
666 default:
667 hdmastarted=((HDMA5&0x80)>>7)+1;
668 if (hdmastarted==2) {
669 HDMA5&=0x7F;
670 break;
671 }
672 for (i=((HDMA5&0x7F)+1)<<4;i>0;i--,hdmadst++,hdmasrc++)
673 vram[VBK&1][hdmadst&0x1FFF]=GetByteAt(hdmasrc);
674 HDMA5=0x80;
675 HDMA1=hdmasrc>>8;
676 HDMA2=hdmasrc&0xF0;
677 HDMA3=(hdmadst>>8)&0x1F;
678 HDMA4=hdmadst&0xF0;
679 hdmastarted=0;
680 break;
681 }
682
683 #ifdef DEBUG
684 printf("HDMA5<= %02X (%i) (%04X=>%04X) at 0x%04X\n",value,
685 hdmastarted,hdmasrc,hdmadst+0x8000,Z80_REG.W.PC);
686 #endif
687 /* for (i=((HDMA5&0x7F)+1)<<4;i>0;i--,dma_d++,dma_s++)
688 vram[VBK&1][dma_d&0x1FFF]=GetByteAt(dma_s);*/
689 break;
690 case 0x56: /* infrared IO */
691 if (!colormode) switch2color();
692 #ifdef DEBUG
693 printf("Fixme: infrared access (%02X at %04X).\n",value,Z80_REG.W.PC);
694 #endif
695 break;
696 case 0x68: /* BG pal write specs */
697 if (!colormode) switch2color();
698 BCPS=value&0xBF;
699 u=GB_BGPAL[(value>>3)&7][(value>>1)&3];
700 BCPD=value&1 ? (u>>8)&0x7F : u&0xFF;
701 break;
702 case 0x69: /* BG pal write data */
703 if (!colormode) switch2color();
704 i=BCPS;
705 if (i&1) { /* high word */
706 u=GB_BGPAL[(i>>3)&7][(i>>1)&3]=(GB_BGPAL[(i>>3)&7][(i>>1)&3]&0xFF)|
707 (value<<8);
708 } else { /* low word */
709 u=GB_BGPAL[(i>>3)&7][(i>>1)&3]=(GB_BGPAL[(i>>3)&7][(i>>1)&3]&0xFF00)|
710 value;
711 }
712 BGPAL[(i>>3)&7][(i>>1)&3]=color_translate(u);
713 i=BCPS=i&0x80 ? (i&0x80)|((i+1)&0x3F) : i;
714 u=GB_BGPAL[(i>>3)&7][(i>>1)&3];
715 BCPD=i&1 ? u>>8 : u&0xFF;
716 break;
717 case 0x6A: /* OBJ pal write specs */
718 if (!colormode) switch2color();
719 OCPS=value&0xBF;
720 u=GB_OBJPAL[(value>>3)&7][(value>>1)&3];
721 OCPD=value&1 ? (u>>8)&0x7F : u&0xFF;
722 break;
723 case 0x6B: /* OBJ pal write data */
724 if (!colormode) switch2color();
725 i=OCPS;
726 if (i&1) { /* high word */
727 u=GB_OBJPAL[(i>>3)&7][(i>>1)&3]=(GB_OBJPAL[(i>>3)&7][(i>>1)&3]&0xFF)|
728 (value<<8);
729 } else { /* low word */
730 u=GB_OBJPAL[(i>>3)&7][(i>>1)&3]=(GB_OBJPAL[(i>>3)&7][(i>>1)&3]&0xFF00)|
731 value;
732 }
733 OBJPAL[(i>>3)&7][(i>>1)&3]=color_translate(u);
734 i=OCPS=i&0x80 ? (i&0x80)|((i+1)&0x3F) : i;
735 u=GB_OBJPAL[(i>>3)&7][(i>>1)&3];
736 OCPD=i&1 ? u>>8 : u&0xFF;
737 break;
738 case 0x70: /* work bank selection */
739 if (!colormode) switch2color();
740 SVBK=value&7;
741 workbanknr=value&7;
742 if (workbanknr==0) workbanknr++;
743 #ifdef HARDDEBUG
744 printf("WRAM bank %i selected.\n",workbanknr);
745 #endif
746 break;
747 }
748 }
749 }
750
SetByteAt(uint addr,uchar value)751 void SetByteAt(uint addr, uchar value)
752 {
753 #ifdef DEBUG
754 if (addr==0xff59)
755 fprintf(OUTSTREAM,"%04X=>%02X accessed at PC: %04X\n",
756 addr,value,Z80_REG.W.PC);
757 /* fprintf(OUTSTREAM,"%d%d ",(value>>5)&1,(value>>4)&1);*/
758 #endif
759
760 switch (addr >> 8) {
761 case 0xFF:IOOut(addr & 0xFF,value);return;
762 default:
763 switch (addr >> 13) {
764 case 0: /* RAM bank enable */
765 if (mbctype==0) {
766 fprintf(OUTSTREAM,"Fixme: No MBC and using SRAM ?\n");
767 fprintf(OUTSTREAM," (written %02X to %04X)\n",value,addr);
768 return;
769 }
770 if ((mbctype==2)&&((addr & 0x0100)>0)) {
771 fprintf(OUTSTREAM,"Fixme: Using MBC2 and writing 0x%02X to 0x%04X.\n",
772 value,addr);
773 return;
774 }
775
776 value&=0x0F;
777 #ifdef HARDDEBUG
778 if ((value!=10)&&(value!=0)) {
779 fprintf(OUTSTREAM,"SRAM disable ? (0x%02X=>0x%04X)\n",value,addr);
780 }
781 #endif
782
783 rambankenabled= value == 10 ? 1 : 0;
784 return;
785 case 1: /* ROM bank select */
786 switch (mbctype) {
787 case 0:
788 if (value!=1) {
789 fprintf(OUTSTREAM,"Fixme: No MBC and using ROM switching ?\n");
790 fprintf(OUTSTREAM," (written %02X to %04X)\n",value,addr);
791 return;
792 }
793 break;
794 case 1:
795 if (mbcmode)
796 rombanknr=value; else
797 rombanknr=(rombanknr&0x60)|(value & 0x1F);
798 if (rombanknr>=romselectmask) {
799 fprintf(OUTSTREAM,"Fixme: ROM bank %d selected.\n",rombanknr);
800 return;
801 }
802 break;
803 case 2:
804 if ((addr & 0x0100)==0) {
805 fprintf(OUTSTREAM,
806 "Fixme: Using MBC2 and writing 0x%02X to 0x%04X.\n",
807 value,addr);
808 return;
809 }
810 if (mbcmode)
811 rombanknr=value; else
812 rombanknr=(rombanknr&0x60)|(value & 0x1F);
813 if (rombanknr>=romselectmask) {
814 fprintf(OUTSTREAM,"Fixme: ROM bank %d selected.\n",value);
815 return;
816 }
817 break;
818 case 5:
819 if (addr>=0x3000) break;
820 if (value>=romselectmask) {
821 fprintf(OUTSTREAM,"Fixme: ROM bank %d selected (PC:%04X).\n",
822 value,Z80_REG.W.PC);
823 value&=romselectmask-1;
824 }
825 rombanknr=value&0x7F;
826 break;
827 }
828
829 if (rombanknr==0) rombanknr++;
830 #ifdef HARDDEBUG
831 fprintf(OUTSTREAM,"ROM select %d (PC:%04X).\n",rombanknr,Z80_REG.W.PC);
832 #endif
833 return;
834 case 2: /* RAM/ROMHI bank select */
835 if ((value&0xF0)>0) return;
836 if (mbctype==2) {
837 fprintf(OUTSTREAM,"Fixme: MBC2 and selecting RAM banks ?\n");
838 fprintf(OUTSTREAM," (written %02X to %04X)\n",value,addr);
839 return;
840 }
841 if ((mbcmode==0)&&(mbctype==1)) { /* ROM hi-addr */
842 if (value>3) {
843 fprintf(OUTSTREAM,"Fixme: 16/8 mode, illegal hi address.\n");
844 fprintf(OUTSTREAM," (written %02X to %04X)\n",value,addr);
845 return;
846 }
847 rombanknr=(rombanknr & 0x1F)|((value&3)<<5);
848 if (rombanknr>=romselectmask) {
849 fprintf(OUTSTREAM,"Fixme: ROM bank %d selected.\n",value);
850 return;
851 }
852 #ifdef DEBUG
853 fprintf(OUTSTREAM,"ROM bank %d selected (hi addr) PC:%04X.\n",
854 rombanknr,Z80_REG.W.PC);
855 #endif
856 return;
857 }
858 rambanknr=value&3;
859
860 if (rambanknr>=sramselectmask) {
861 fprintf(OUTSTREAM,"Fixme: RAM bank %d selected.\n",rambanknr);
862 fprintf(OUTSTREAM," (written %02X to %04X)\n",value,addr);
863 return;
864 }
865 #ifdef DEBUG
866 fprintf(OUTSTREAM,"RAM bank %d selected.\n",rambanknr);
867 #endif
868 return;
869 case 3: /* MBC mode select */
870 if ((value&0xF0)>0) return;
871 if (mbctype==2) {
872 fprintf(OUTSTREAM,"Fixme: MBC2 and selecting modes ?\n");
873 fprintf(OUTSTREAM," (at PC: %04X written %02X to %04X)\n",
874 Z80_REG.W.PC,value,addr);
875 return;
876 }
877 if (mbctype==5) { /* clock counter latch */
878 #ifdef DEBUG
879 fprintf(OUTSTREAM,"Fixme: MBC5 clock funcs not implemented (%04X).\n",
880 Z80_REG.W.PC);
881 #endif
882 return;
883 }
884 mbcmode=value & 1;
885 #ifdef DEBUG
886 fprintf(OUTSTREAM,"MBC mode %s selected.\n",mbcmode == 0 ? "16/8" : "4/32");
887 #endif
888 return;
889 case 4: /* VRAM access */
890 /* ************************************** */
891 /* *** NOT CHECKING IF ACCESSIBLE !!! *** */
892 /* ************************************** */
893 /* fprintf(OUTSTREAM,"VRAM access: %04X at PC %04X\n",addr,Z80_REG.W.PC); */
894 vram[VBK&1][addr & 0x1FFF]=value;
895 return;
896 case 5: /* SRAM access */
897 value=ar_checkwrite(addr,value);
898
899 if (rambankenabled!=0)
900 sram[rambanknr][addr & 0x1FFF]=value;
901 return;
902 case 6: /* internal RAM and OAM */
903 case 7: /* w/o IO (0xFF00-) */
904 if (addr<0xFE00) {
905 /* internal RAM with echoing ! */
906
907 value=ar_checkwrite((addr&0x1FFF)+0xC000,value);
908 value=ar_checkwrite((addr&0x1FFF)+0xE000,value);
909 switch (addr>>12) {
910 case 0xC:
911 case 0xE:
912 iram[0][addr & 0x0FFF]=value;
913 break;
914 case 0xD:
915 case 0xF:
916 iram[workbanknr][addr & 0x0FFF]=value;
917 break;
918 }
919 } else {
920 /* OAM access */
921 /* ************************************** */
922 /* *** NOT CHECKING IF ACCESSIBLE !!! *** */
923 /* *** THIS COULD BE FATAL !!! *** */
924 /* ************************************** */
925 oam[addr & 0xFF]=value;
926 }
927 return;
928 }
929 }
930 }
931
switch2color(void)932 void switch2color(void)
933 {
934 int k,l;
935 if (force_stdgameboy) return;
936
937 switch (bitmapbits) {
938 case 8:
939 scanline=cgb_scanline8;
940 break;
941 case 16:
942 scanline=cgb_scanline16;
943 break;
944 case 32:
945 scanline=cgb_scanline32;
946 break;
947 default:
948 printf("Error: Cannot handle resolution %i, yet.\n",bitmapbits);
949 exit(1);
950 }
951 for (k=0;k<8;k++)
952 for (l=0;l<4;l++) {
953 BGPAL[k][l]= color_translate(GB_BGPAL[k][l] );
954 OBJPAL[k][l]=color_translate(GB_OBJPAL[k][l]);
955 }
956
957 #ifndef DOS
958 fprintf(OUTSTREAM,"Gameboy COLOR rom detected.\n");
959 #endif
960 colormode=1;
961 }
962
963 /* for games with battery: saving routine */
savestate(void)964 void savestate(void)
965 {
966 FILE *fp;
967 int j,zeros,b;
968
969 fprintf(OUTSTREAM,"Saving state to %s ... ",sramfile);
970 fp=fopen(sramfile,"wb");
971 if (fp) {
972 zeros=0;j=0;
973 while (j<sramsize) {
974 b=sram[j / srambanksize][j % srambanksize];
975 if (b==0) zeros++;
976 else {
977 while (zeros) { fputc(0,fp);zeros--;}
978 fputc(b,fp);
979 }
980 j++;
981 }
982 fclose(fp);
983 if (zeros==sramsize) {
984 fprintf(OUTSTREAM,"(empty) ");
985 if (unlink(sramfile)) fprintf(OUTSTREAM,"erase FAILED, ");
986 }
987 fprintf(OUTSTREAM,"done.\n");
988 } else {
989 fprintf(OUTSTREAM,"ERROR\n");
990 }
991 }
992
tidyup(void)993 void tidyup(void)
994 {
995 unsigned int i;
996
997 donesys();
998
999 fprintf(OUTSTREAM,"Freeing resources ... ");
1000 for (i=0;i<GB_WORKBANKCOUNT;i++) {
1001 if (iram[i]!=NULL) free(iram[i]);
1002 }
1003 if (oam!=NULL) free(oam);
1004 if (io!=NULL) free(io);
1005 if (vram[0]!=NULL) free(vram[0]);
1006 if (vram[1]!=NULL) free(vram[1]);
1007 out_ok;
1008
1009 fprintf(OUTSTREAM,"Freeing ROM/RAM ...");
1010 for (i=0;i<sramselectmask;i++)
1011 if (sram[i]!=NULL) free(sram[i]);
1012 for (i=0;i<romselectmask;i++)
1013 if (bank[i]!=NULL) free(bank[i]);
1014 out_ok;
1015 return;
1016 }
1017
initcart(char * cartfile)1018 int initcart(char *cartfile)
1019 {
1020 FILE *fp;
1021 unsigned int i,l;
1022 int j,k;
1023 char romname[17];
1024 char filename[512];
1025 uint cs=0,ccs=0;
1026
1027 #ifdef UNIX
1028 #define CCLOSE if (!strcmp(&cartfile[strlen(cartfile)-3],".gz")) pclose(fp); else \
1029 fclose(fp)
1030 #else
1031 #define CCLOSE fclose(fp)
1032 #endif
1033
1034 #ifdef VERBOSE
1035 fprintf(OUTSTREAM,"Opening cart: %s\n",cartfile);
1036 #endif
1037
1038 for (i=0;i<GB_MAXROMBANKCOUNT;i++)
1039 bank[i]=NULL;
1040
1041 for (i=0;i<GB_WORKBANKCOUNT;i++)
1042 iram[i]=NULL;
1043
1044 oam=NULL;io=NULL;
1045 vram[0]=NULL;vram[1]=NULL;
1046 for (i=0;i<sramselectmask;i++)
1047 sram[i]=NULL;
1048 for (i=0;i<romselectmask;i++)
1049 bank[i]=NULL;
1050
1051 #ifdef UNIX
1052 if (!strcmp(&cartfile[strlen(cartfile)-3],".gz")) {
1053 fprintf(OUTSTREAM,"Opening gzipped.\n");
1054 sprintf(filename,"gunzip -c \"%s\"",cartfile);
1055 if ((fp=popen(filename,"r"))==NULL) {
1056 fprintf(stderr,"Failed to open gzipped cartridge.\n");
1057 exit(1);
1058 }
1059
1060 pclose(fp);
1061
1062 if ((fp=popen(filename,"r"))==NULL) {
1063 fprintf(stderr,"Failed to open gzipped cartridge.\n");
1064 exit(1);
1065 }
1066 } else {
1067 #endif
1068 if ((fp=fopen(cartfile,"r"))==NULL) {
1069 sprintf(filename,"%s.gb",cartfile);
1070 if ((fp=fopen(filename,"r"))==NULL) {
1071 sprintf(filename,"%s.GB",cartfile);
1072 if ((fp=fopen(filename,"r"))==NULL) {
1073 fprintf(stderr,"Failed to open cartridge.\n");
1074 exit(1);
1075 }
1076 }
1077 }
1078 #ifdef UNIX
1079 }
1080 #endif
1081
1082 /* alloc ROM banks */
1083 i=0;
1084 while (!feof(fp)) {
1085 if (i>=GB_MAXROMBANKCOUNT) {
1086 fprintf(stderr,"The cartridge is too big.\n");
1087 CCLOSE;
1088 return 1;
1089 }
1090 bank[i]=malloc(GB_ROMBANKSIZE);
1091 if (bank[i]==NULL) {
1092 fprintf(stderr,"Out of memory.\n");
1093 CCLOSE;
1094 exit(1);
1095 }
1096
1097 if ((l=fread(bank[i],1,GB_ROMBANKSIZE,fp))==0) break;
1098
1099 if (l!=GB_ROMBANKSIZE) {
1100 fprintf(stderr,"error reading data (reading %i,returned: %d).\n",i,l);
1101 exit(1);
1102 }
1103
1104 if (i==0) {
1105 ccs=(((uint)bank[0][0x14E]<< 8)|
1106 bank[0][0x14F]);
1107 cs=0;
1108 cs-=bank[0][0x14E];
1109 cs-=bank[0][0x14F];
1110 }
1111
1112 for (k=0;k<GB_ROMBANKSIZE;k++) cs+=bank[i][k];
1113 i++;
1114 }
1115 romselectmask=j=i;
1116 CCLOSE;
1117
1118 if (ccs!=cs) {
1119 out_failed;
1120 fprintf(stderr,"Checksum failure (is: %04X should be: %04X).\n",cs,ccs);
1121 fprintf(stderr,"Cartridge file broken ?\n");
1122 return 1;
1123 } else out_ok;
1124
1125 /* cart check --- nintendo logo */
1126
1127 for (i=0;i<0x30;i++)
1128 if (bank[0][0x104+i]!=Nintendo_Logo[i])
1129 {
1130 fprintf(stderr,"I don't recognize this rom.\n");
1131 fprintf(stderr,"Nintendo logo not found.\n");
1132 return 1;
1133 }
1134
1135 for (i=0;i<16;i++)
1136 romname[i]=bank[0][0x134+i];
1137 romname[16]=0;
1138 fprintf(OUTSTREAM,"Rom: %s\nCheck complete.\n",romname);
1139
1140 /* figure out the MBC type */
1141 fprintf(OUTSTREAM,"MBC type (%02X): ",bank[0][0x147]);
1142 switch (bank[0][0x147]) {
1143 case 0:
1144 fprintf(OUTSTREAM,"ROM ONLY");
1145 mbctype=0;
1146 break;
1147 case 1:
1148 mbctype=1;
1149 fprintf(OUTSTREAM,"ROM+MBC1");
1150 break;
1151 case 2:
1152 mbctype=1;
1153 fprintf(OUTSTREAM,"ROM+MBC1+SRAM");
1154 break;
1155 case 3:
1156 mbctype=1;
1157 fprintf(OUTSTREAM,"ROM+MBC1+RAM+BATTERY");
1158 break;
1159 case 5:
1160 mbctype=2;
1161 fprintf(OUTSTREAM,"ROM+MBC2");
1162 break;
1163 case 6:
1164 mbctype=2;
1165 fprintf(OUTSTREAM,"ROM+MBC2+BATTERY");
1166 break;
1167 case 8:
1168 mbctype=0;
1169 fprintf(OUTSTREAM,"ROM+SRAM");
1170 break;
1171 case 9:
1172 mbctype=0;
1173 fprintf(OUTSTREAM,"ROM+SRAM+BATTERY");
1174 break;
1175 case 0x10:
1176 case 0x13:
1177 case 0x1C:
1178 mbctype=5;
1179 fprintf(OUTSTREAM,"ROM+MBC5 (?)");
1180 break;
1181 case 0x19:
1182 mbctype=5;
1183 fprintf(OUTSTREAM,"ROM+MBC5");
1184 break;
1185 case 0x1A:
1186 mbctype=5;
1187 fprintf(OUTSTREAM,"ROM+SRAM+MBC5");
1188 break;
1189 case 0x1B:
1190 case 0x1E:
1191 mbctype=5;
1192 fprintf(OUTSTREAM,"MBC5+ROM+SRAM+BATTERY");
1193 break;
1194 case 255: /* HuC1 - could be buggy */
1195 mbctype=1;
1196 fprintf(OUTSTREAM,"Warning: HuC1 detected ... this is not supported.");
1197 break;
1198 default:
1199 fprintf(stderr,
1200 "\nI don't know this cartridge type (%02X). Sorry ...\n",
1201 bank[0][0x147]);
1202 fprintf(stderr,"You can report this to me. (Thanks)\n");
1203 return 1;
1204 }
1205 fprintf(OUTSTREAM,"\n");
1206
1207 /* allocate RAMs 'n co */
1208 vram[0]=calloc(GB_VRAMSIZE,1);
1209 vram[1]=calloc(GB_VRAMSIZE,1);
1210 io=calloc(GB_IOAREASIZE,1);
1211 oam=calloc(GB_OAMSIZE,1);
1212 for (i=0;i<GB_WORKBANKCOUNT;i++)
1213 if ((iram[i]=calloc(GB_WORKRAMBANKSIZE,1))==NULL) {
1214 fprintf(OUTSTREAM,"Failed to allocate 4kB WORKRAM.\n");
1215 return 1;
1216 }
1217
1218 if ((vram[0]==NULL)||(vram[1]==NULL)||(io==NULL)||(oam==NULL))
1219 return 1;
1220
1221 /* alloc SRAM banks */
1222
1223 srambanksize=0x2000;
1224 for (i=0;i<4;i++) {
1225 if ((sram[i]=calloc(srambanksize,1))==NULL) {
1226 fprintf(OUTSTREAM,"Failed to allocate 8kB SRAM.\n");
1227 return 1;
1228 }
1229 }
1230 sramsize=0x8000;sramselectmask=4;
1231
1232 #ifdef VERBOSE
1233 fprintf(OUTSTREAM,"Allocated SRAM (%d kB).\n",sramsize/1024);
1234 #endif
1235
1236 strcpy(sramfile,cartfile);
1237 *strrchr(sramfile,'.')=0;
1238 strcat(sramfile,".GBS");
1239 fprintf(OUTSTREAM,"Trying to open SRAM-file '%s' ... ",sramfile);
1240 fp=fopen(sramfile,"rb");
1241 if (fp!=NULL) {
1242 fseek(fp,0,SEEK_END);
1243 j=ftell(fp);rewind(fp);
1244 if (j<=sramsize) {
1245 k=GB_SRAMBANKCOUNT[bank[0][0x149]];
1246 if (k==0) k++;
1247 i=0;
1248 while (j>0) {
1249 l=j>srambanksize ? srambanksize : j;
1250 cs=fread(sram[i++],1,l,fp);
1251 if (cs<l) {
1252 fprintf(OUTSTREAM,"read error (wanted %d, got %d)\n",l,cs);
1253 CCLOSE;
1254 return 1;
1255 }
1256 j-=l;
1257 }
1258 out_ok;
1259 } else {
1260 fprintf(OUTSTREAM,"corrupt state\n");
1261 }
1262 CCLOSE;
1263 } else {
1264 fprintf(OUTSTREAM,"not found\n");
1265 }
1266
1267
1268 /* mem init */
1269 for (i=0;i<0x100;i++)
1270 io[i]=Area_0xFF00_init[i];
1271
1272 /* init registers */
1273 Z80_REG.W.AF= force_stdgameboy ? 0x01B0 : 0x11B0;
1274
1275 Z80_REG.W.BC=0x0013;
1276 Z80_REG.W.DE=0x00D8;
1277 Z80_REG.W.HL=0x014D;
1278 Z80_REG.W.SP=0xFFFE;
1279 Z80_REG.W.PC=0x0100;
1280 Z80_HALTED=Z80_IE=0;
1281 Z80_CPUCLKS=0;
1282
1283 /* and stuff */
1284 rombanknr=1;workbanknr=1;
1285 rambanknr=0;
1286 rambankenabled=0;
1287 colormode=mbcmode=0;
1288 newjoypadstate=joypadstate=0xFF;
1289 timerclks=timerfreq=GB_TIMERFRQ[TAC&0x03];
1290 dividerclks=GB_DIVLOAD;
1291 lcdphase=0;STAT|=2; /* lcd phase 2 */
1292 lcdclks=GB_VCLKS[0];
1293 IE=0x00;/* IM=0xFF; */
1294 ABORT_EMULATION=0;
1295 joypadclks=GB_JOYCLKS;
1296 soundcounter=-1;
1297 vblankdelay=GB_VBLANKDELAYCLKS;
1298 vblankoccured=0;
1299 SVBK=VBK=KEY1=0x00;
1300 hdmastarted=hdmasrc=hdmadst=0;
1301 snd_updateclks=0xFFFF;
1302 serialioclks=0;
1303
1304 if (!(i=initsys())) {
1305 switch (bitmapbits) {
1306 case 8:scanline=gb_scanline8;break;
1307 case 16:scanline=gb_scanline16;break;
1308 case 32:scanline=gb_scanline32;break;
1309 default:
1310 printf("Error: Cannot handle resolution %i\n",bitmapbits);
1311 return 1;
1312 }
1313 }
1314
1315 return i;
1316 }
1317
SetWordAt(uint addr,uint value)1318 void SetWordAt(uint addr,uint value)
1319 {
1320 SetByteAt(addr,(uchar)(value & 0xFF));
1321 SetByteAt(addr+1,(uchar)(value >> 8));
1322 }
1323
1324 #define do_tilepix(pixeltype, pack) \
1325 {\
1326 unsigned int zpos;\
1327 zpos=(unsigned int)x;\
1328 \
1329 if (!doublesize) {\
1330 pixeltype *p; \
1331 \
1332 p=(pixeltype *)lcdbuffer+y+x;\
1333 \
1334 *p++=FPAL[zbuffer[zpos++]=tilepix >> 14];\
1335 *p++=FPAL[zbuffer[zpos++]=(tilepix >> 6)&0x03];\
1336 *p++=FPAL[zbuffer[zpos++]=(tilepix >> 12)&0x03];\
1337 *p++=FPAL[zbuffer[zpos++]=(tilepix >> 4)&0x03];\
1338 *p++=FPAL[zbuffer[zpos++]=(tilepix >> 10)&0x03];\
1339 *p++=FPAL[zbuffer[zpos++]=(tilepix >> 2)&0x03];\
1340 *p++=FPAL[zbuffer[zpos++]=(tilepix >> 8)&0x03];\
1341 *p=FPAL[zbuffer[zpos]=tilepix &0x03];\
1342 } else {\
1343 pixeltype *p; \
1344 \
1345 p=(pixeltype *)lcdbuffer+y+(x<<1);\
1346 \
1347 *(p+1)=*p=\
1348 FPAL[zbuffer[zpos++]=tilepix >> 14]; \
1349 p+=pack; \
1350 \
1351 *(p+1)=*p=\
1352 FPAL[zbuffer[zpos++]=(tilepix >> 6)&0x03];\
1353 p+=pack; \
1354 \
1355 *(p+1)=*p=\
1356 FPAL[zbuffer[zpos++]=(tilepix >> 12)&0x03];\
1357 p+=pack; \
1358 \
1359 *(p+1)=*p=\
1360 FPAL[zbuffer[zpos++]=(tilepix >> 4)&0x03];\
1361 p+=pack; \
1362 \
1363 *(p+1)=*p=\
1364 FPAL[zbuffer[zpos++]=(tilepix >> 10)&0x03];\
1365 p+=pack; \
1366 \
1367 *(p+1)=*p=\
1368 FPAL[zbuffer[zpos++]=(tilepix >> 2)&0x03];\
1369 p+=pack; \
1370 \
1371 *(p+1)=*p=\
1372 FPAL[zbuffer[zpos++]=(tilepix >> 8)&0x03];\
1373 p+=pack; \
1374 \
1375 *(p+1)=*p=\
1376 FPAL[zbuffer[zpos]=tilepix&0x03];\
1377 \
1378 }\
1379 }
1380
gb_scanline8(void)1381 void gb_scanline8(void)
1382 {
1383 int x,y,tx,ty,xc,tmp;
1384 uchar *tileofs,*tiledata,*sprofs;
1385 uchar tile,tile1,tile2;
1386 uint tilepix;
1387 uchar zbuffer[GB_XBUFFERSIZE];
1388 uchar FPAL[4];
1389
1390 FPAL[0]=(uchar)GB_STDPAL[BGP & 0x03];
1391 FPAL[1]=(uchar)GB_STDPAL[(BGP >> 2)& 0x03];
1392 FPAL[2]=(uchar)GB_STDPAL[(BGP >> 4)& 0x03];
1393 FPAL[3]=(uchar)GB_STDPAL[BGP >> 6];
1394
1395
1396 y=LY*GB_XBUFFERSIZE;
1397 if (doublesize) y<<=2;
1398
1399 if (LCDC & 0x01) { /* if BG enabled */
1400
1401
1402 tileofs=vram[0]
1403 +((((LY+SCY)&0xFF) >> 3)<<5)+(LCDC & 0x08 ? 0x1C00 : 0x1800);
1404 xc=((LCDC & 0x20)&&(WY<=LY) ? ((WX<7 ? 0 : WX-7) >> 3) : 21);
1405 xc=xc>21 ? 21 : xc;
1406
1407 for (tx=0,x=8-(SCX & 7);tx<xc;tx++,x+=8) {
1408 tile=tileofs[(tx+(SCX>>3))&0x1F];
1409 tiledata=LCDC & 0x10 ? vram[0]+(int)tile*16
1410 : vram[0]+0x1000+(int)((signed char)tile)*16;
1411 tiledata+=((LY+SCY)&7)<<1;
1412 tilepix=((uint)(tiledata[1]&0xAA)<<8)|((uint)(tiledata[0]&0xAA)<<7)|
1413 (tiledata[0]&0x55)|((tiledata[1]&0x55)<<1);
1414
1415 do_tilepix(uchar, 2);
1416
1417 }
1418 } else { /* if BG not enabled */
1419 memset(zbuffer,0,GB_XBUFFERSIZE);
1420 memset((uchar*)lcdbuffer+y, FPAL[0],
1421 doublesize ? GB_XBUFFERSIZE<<1 : GB_XBUFFERSIZE);
1422 }
1423
1424
1425 if ((LCDC & 0x20)&&(WY<=LY)&&(WX<167)) { /* if window is on and visible */
1426
1427 y=LY*GB_XBUFFERSIZE;
1428 if (doublesize) y<<=2;
1429
1430 x=WX+1;xc=167-WX;
1431 tileofs=vram[0]+(((LY-WY) >> 3)<<5)+(LCDC & 0x40 ? 0x1C00 : 0x1800);
1432
1433 for (tx=0;xc>0;xc-=8,x+=8,tx++) {
1434 tiledata=LCDC & 0x10 ? vram[0]+(int)tileofs[tx]*16
1435 : vram[0]+0x1000+(int)((signed char)tileofs[tx])*16;
1436 tiledata+=((LY-WY)&7)<<1;
1437 tilepix=((uint)(tiledata[1]&0xAA)<<8)|((uint)(tiledata[0]&0xAA)<<7)|
1438 (tiledata[0]&0x55)|((tiledata[1]&0x55)<<1);
1439
1440 do_tilepix(uchar, 2);
1441 }
1442 }
1443
1444 if (LCDC & 0x02) { /* sprites enabled */
1445 ty=LCDC & 0x04 ? 16 : 8;
1446
1447 y=LY*GB_XBUFFERSIZE;
1448 if (doublesize) y<<=2;
1449
1450 /* background sprites */
1451 for (xc=GB_SPRITECOUNT-1,sprofs=oam+0x9C;xc>=0;xc--,sprofs-=4) {
1452 tmp=LY-sprofs[0]+16;
1453 if ((sprofs[3]&0x80)&&(tmp>=0)&&(tmp<ty)&&
1454 (sprofs[1]<GB_LCDXSCREENSIZE+8)) {
1455 if (sprofs[3]&0x40) tmp=ty-1-tmp;
1456 tiledata=vram[0]
1457 +(((uint)(sprofs[2] & (LCDC & 0x04 ? 0xFE : 0xFF)))<<4)
1458 +(tmp<<1);
1459 if (sprofs[3]&0x20) {
1460 tile1=H_Flip[tiledata[0]];
1461 tile2=H_Flip[tiledata[1]];
1462 } else {
1463 tile1=tiledata[0];
1464 tile2=tiledata[1];
1465 }
1466 tilepix=((uint)(tile2&0xAA)<<8)|((uint)(tile1&0xAA)<<7)|
1467 (tile1&0x55)|((tile2&0x55)<<1);
1468 x=sprofs[1];
1469
1470 if (sprofs[3]&0x10) {
1471 FPAL[0]=(uchar)GB_STDPAL[OBP1 & 0x03];
1472 FPAL[1]=(uchar)GB_STDPAL[(OBP1 >> 2)& 0x03];
1473 FPAL[2]=(uchar)GB_STDPAL[(OBP1 >> 4)& 0x03];
1474 FPAL[3]=(uchar)GB_STDPAL[OBP1 >> 6];
1475 } else {
1476 FPAL[0]=(uchar)GB_STDPAL[OBP0 & 0x03];
1477 FPAL[1]=(uchar)GB_STDPAL[(OBP0 >> 2)& 0x03];
1478 FPAL[2]=(uchar)GB_STDPAL[(OBP0 >> 4)& 0x03];
1479 FPAL[3]=(uchar)GB_STDPAL[OBP0 >> 6];
1480 }
1481
1482 if (!doublesize ) {
1483 if ((zbuffer[x]==0)&&(tilepix>>14))
1484 ((uchar *)lcdbuffer)[y+x]=FPAL[tilepix >> 14];
1485 if ((zbuffer[x+1]==0)&&((tilepix>>6)&0x03))
1486 ((uchar *)lcdbuffer)[y+x+1]=FPAL[(tilepix >> 6)&0x03];
1487 if ((zbuffer[x+2]==0)&&((tilepix>>12)&0x03))
1488 ((uchar *)lcdbuffer)[y+x+2]=FPAL[(tilepix >> 12)&0x03];
1489 if ((zbuffer[x+3]==0)&&((tilepix>>4)&0x03))
1490 ((uchar *)lcdbuffer)[y+x+3]=FPAL[(tilepix >> 4)&0x03];
1491 if ((zbuffer[x+4]==0)&&((tilepix>>10)&0x03))
1492 ((uchar *)lcdbuffer)[y+x+4]=FPAL[(tilepix >> 10)&0x03];
1493 if ((zbuffer[x+5]==0)&&((tilepix>>2)&0x03))
1494 ((uchar *)lcdbuffer)[y+x+5]=FPAL[(tilepix >> 2)&0x03];
1495 if ((zbuffer[x+6]==0)&&((tilepix>>8)&0x03))
1496 ((uchar *)lcdbuffer)[y+x+6]=FPAL[(tilepix >> 8)&0x03];
1497 if ((zbuffer[x+7]==0)&&(tilepix&0x03))
1498 ((uchar *)lcdbuffer)[y+x+7]=FPAL[tilepix&0x03];
1499 } else {
1500 if ((zbuffer[x]==0)&&(tilepix>>14))
1501 ((uchar *)lcdbuffer)[y+(x<<1) ]=
1502 ((uchar *)lcdbuffer)[y+(x<<1)+1]=FPAL[tilepix >> 14];
1503 if ((zbuffer[x+1]==0)&&((tilepix>>6)&0x03))
1504 ((uchar *)lcdbuffer)[y+(x<<1)+2]=
1505 ((uchar *)lcdbuffer)[y+(x<<1)+3]=FPAL[(tilepix >> 6)&0x03];
1506 if ((zbuffer[x+2]==0)&&((tilepix>>12)&0x03))
1507 ((uchar *)lcdbuffer)[y+(x<<1)+4]=
1508 ((uchar *)lcdbuffer)[y+(x<<1)+5]=FPAL[(tilepix >> 12)&0x03];
1509 if ((zbuffer[x+3]==0)&&((tilepix>>4)&0x03))
1510 ((uchar *)lcdbuffer)[y+(x<<1)+6]=
1511 ((uchar *)lcdbuffer)[y+(x<<1)+7]=FPAL[(tilepix >> 4)&0x03];
1512 if ((zbuffer[x+4]==0)&&((tilepix>>10)&0x03))
1513 ((uchar *)lcdbuffer)[y+(x<<1)+8]=
1514 ((uchar *)lcdbuffer)[y+(x<<1)+9]=FPAL[(tilepix >> 10)&0x03];
1515 if ((zbuffer[x+5]==0)&&((tilepix>>2)&0x03))
1516 ((uchar *)lcdbuffer)[y+(x<<1)+10]=
1517 ((uchar *)lcdbuffer)[y+(x<<1)+11]=FPAL[(tilepix >> 2)&0x03];
1518 if ((zbuffer[x+6]==0)&&((tilepix>>8)&0x03))
1519 ((uchar *)lcdbuffer)[y+(x<<1)+12]=
1520 ((uchar *)lcdbuffer)[y+(x<<1)+13]=FPAL[(tilepix >> 8)&0x03];
1521 if ((zbuffer[x+7]==0)&&(tilepix&0x03))
1522 ((uchar *)lcdbuffer)[y+(x<<1)+14]=
1523 ((uchar *)lcdbuffer)[y+(x<<1)+15]=FPAL[tilepix&0x03];
1524 }
1525 }
1526 }
1527
1528 /* foreground sprites */
1529 for (xc=GB_SPRITECOUNT-1,sprofs=oam+0x9C;xc>=0;xc--,sprofs-=4) {
1530 tmp=LY-sprofs[0]+16;
1531 if (((sprofs[3]&0x80)==0)&&(tmp>=0)&&(tmp<ty)&&
1532 (sprofs[1]<GB_LCDXSCREENSIZE+8)) {
1533 if (sprofs[3]&0x40) tmp=ty-1-tmp;
1534 tiledata=vram[0]
1535 +(((uint)(sprofs[2] & (LCDC & 0x04 ? 0xFE : 0xFF)))<<4)
1536 +(tmp<<1);
1537 if (sprofs[3]&0x20) {
1538 tile1=H_Flip[tiledata[0]];
1539 tile2=H_Flip[tiledata[1]];
1540 } else {
1541 tile1=tiledata[0];
1542 tile2=tiledata[1];
1543 }
1544 tilepix=((uint)(tile2&0xAA)<<8)|((uint)(tile1&0xAA)<<7)|
1545 (tile1&0x55)|((tile2&0x55)<<1);
1546 x=sprofs[1];
1547
1548 if (sprofs[3]&0x10) {
1549 FPAL[0]=(uchar)GB_STDPAL[OBP1 & 0x03];
1550 FPAL[1]=(uchar)GB_STDPAL[(OBP1 >> 2)& 0x03];
1551 FPAL[2]=(uchar)GB_STDPAL[(OBP1 >> 4)& 0x03];
1552 FPAL[3]=(uchar)GB_STDPAL[OBP1 >> 6];
1553 } else {
1554 FPAL[0]=(uchar)GB_STDPAL[OBP0 & 0x03];
1555 FPAL[1]=(uchar)GB_STDPAL[(OBP0 >> 2)& 0x03];
1556 FPAL[2]=(uchar)GB_STDPAL[(OBP0 >> 4)& 0x03];
1557 FPAL[3]=(uchar)GB_STDPAL[OBP0 >> 6];
1558 }
1559
1560 if (!doublesize) {
1561 if (tilepix>>14)
1562 ((uchar *)lcdbuffer)[y+x]=FPAL[tilepix >> 14];
1563 if ((tilepix>>6)&0x03)
1564 ((uchar *)lcdbuffer)[y+x+1]=FPAL[(tilepix >> 6)&0x03];
1565 if ((tilepix>>12)&0x03)
1566 ((uchar *)lcdbuffer)[y+x+2]=FPAL[(tilepix >> 12)&0x03];
1567 if ((tilepix>>4)&0x03)
1568 ((uchar *)lcdbuffer)[y+x+3]=FPAL[(tilepix >> 4)&0x03];
1569 if ((tilepix>>10)&0x03)
1570 ((uchar *)lcdbuffer)[y+x+4]=FPAL[(tilepix >> 10)&0x03];
1571 if ((tilepix>>2)&0x03)
1572 ((uchar *)lcdbuffer)[y+x+5]=FPAL[(tilepix >> 2)&0x03];
1573 if ((tilepix>>8)&0x03)
1574 ((uchar *)lcdbuffer)[y+x+6]=FPAL[(tilepix >> 8)&0x03];
1575 if (tilepix&0x03)
1576 ((uchar *)lcdbuffer)[y+x+7]=FPAL[tilepix&0x03];
1577 } else {
1578 if (tilepix>>14)
1579 ((uchar *)lcdbuffer)[y+(x<<1) ]=
1580 ((uchar *)lcdbuffer)[y+(x<<1)+1]=FPAL[tilepix >> 14];
1581 if ((tilepix>>6)&0x03)
1582 ((uchar *)lcdbuffer)[y+(x<<1)+2]=
1583 ((uchar *)lcdbuffer)[y+(x<<1)+3]=FPAL[(tilepix >> 6)&0x03];
1584 if ((tilepix>>12)&0x03)
1585 ((uchar *)lcdbuffer)[y+(x<<1)+4]=
1586 ((uchar *)lcdbuffer)[y+(x<<1)+5]=FPAL[(tilepix >> 12)&0x03];
1587 if ((tilepix>>4)&0x03)
1588 ((uchar *)lcdbuffer)[y+(x<<1)+6]=
1589 ((uchar *)lcdbuffer)[y+(x<<1)+7]=FPAL[(tilepix >> 4)&0x03];
1590 if ((tilepix>>10)&0x03)
1591 ((uchar *)lcdbuffer)[y+(x<<1)+8]=
1592 ((uchar *)lcdbuffer)[y+(x<<1)+9]=FPAL[(tilepix >> 10)&0x03];
1593 if ((tilepix>>2)&0x03)
1594 ((uchar *)lcdbuffer)[y+(x<<1)+10]=
1595 ((uchar *)lcdbuffer)[y+(x<<1)+11]=FPAL[(tilepix >> 2)&0x03];
1596 if ((tilepix>>8)&0x03)
1597 ((uchar *)lcdbuffer)[y+(x<<1)+12]=
1598 ((uchar *)lcdbuffer)[y+(x<<1)+13]=FPAL[(tilepix >> 8)&0x03];
1599 if (tilepix&0x03)
1600 ((uchar *)lcdbuffer)[y+(x<<1)+14]=
1601 ((uchar *)lcdbuffer)[y+(x<<1)+15]=FPAL[tilepix&0x03];
1602 }
1603 }
1604 }
1605
1606
1607 }
1608 }
1609
cgb_scanline8(void)1610 void cgb_scanline8(void)
1611 {
1612 int x,y,tx,ty,xc,tmp;
1613 uchar *tileofs1,*tileofs2,*tiledata,*sprofs;
1614 uchar tile,tile1,tile2,tile_a;
1615 uint tilepix,tilenum;
1616 uchar zbuffer[GB_XBUFFERSIZE];
1617 uchar FPAL[4];
1618
1619 y=LY*GB_XBUFFERSIZE;
1620 if (doublesize) y<<=2;
1621
1622 if (LCDC & 0x01) { /* if BG enabled */
1623 tilenum=((((LY+SCY)&0xFF) >> 3)<<5)+(LCDC & 0x08 ? 0x1C00 : 0x1800);
1624 tileofs1=vram[0]+tilenum;
1625 tileofs2=vram[1]+tilenum;
1626 xc=((LCDC & 0x20)&&(WY<=LY) ? ((WX<7 ? 0 : WX-7) >> 3) : 21);
1627 xc=xc>21 ? 21 : xc;
1628 for (tx=0,x=8-(SCX & 7);tx<xc;tx++,x+=8) {
1629 tile=tileofs1[(tx+(SCX>>3))&0x1F];
1630 tile_a=tileofs2[(tx+(SCX>>3))&0x1F];
1631 tiledata=LCDC & 0x10 ? vram[(tile_a>>3)&1]+((int)tile<<4)
1632 : vram[(tile_a>>3)&1]+0x1000+((int)((signed char)tile)<<4);
1633 tiledata+=(tile_a&0x40) ? (7-((LY+SCY)&7))<<1:((LY+SCY)&7)<<1;
1634 tile1=tiledata[0];tile2=tiledata[1];
1635 if (tile_a&0x20) {tile1=H_Flip[tile1];tile2=H_Flip[tile2];}
1636
1637 tilepix=((uint)(tile2&0xAA)<<8)|((uint)(tile1&0xAA)<<7)|
1638 (tile1&0x55)|((tile2&0x55)<<1);
1639
1640 FPAL[0]=(uchar)BGPAL[tile_a&7][0];
1641 FPAL[1]=(uchar)BGPAL[tile_a&7][1];
1642 FPAL[2]=(uchar)BGPAL[tile_a&7][2];
1643 FPAL[3]=(uchar)BGPAL[tile_a&7][3];
1644
1645 do_tilepix(uchar, 2);
1646 }
1647 } else { /* if BG not enabled */
1648 memset(zbuffer,0,GB_XBUFFERSIZE);
1649 memset((uchar*)lcdbuffer+y, 0, /* 0 or background ? */
1650 doublesize ? GB_XBUFFERSIZE<<1 : GB_XBUFFERSIZE);
1651 }
1652
1653 if ((LCDC & 0x20)&&(WY<=LY)&&(WX<167)) { /* if window is on and visible */
1654
1655 y=LY*GB_XBUFFERSIZE;
1656 if (doublesize) y<<=2;
1657
1658 x=WX+1;xc=167-WX;
1659 tilenum=(((LY-WY) >> 3)<<5)+(LCDC & 0x40 ? 0x1C00 : 0x1800);
1660 tileofs1=vram[0]+tilenum;
1661 tileofs2=vram[1]+tilenum;
1662 for (tx=0;xc>0;xc-=8,x+=8,tx++) {
1663 tile_a=tileofs2[tx];
1664 tiledata=LCDC & 0x10 ? vram[(tile_a>>3)&1]+((int)tileofs1[tx]<<4)
1665 : vram[(tile_a>>3)&1]+0x1000+((int)((signed char)tileofs1[tx])<<4);
1666
1667 tiledata+=(tile_a&0x40) ? (7-((LY-WY)&7))<<1:((LY-WY)&7)<<1;
1668 tile1=tiledata[0];tile2=tiledata[1];
1669 if (tile_a&0x20) {tile1=H_Flip[tile1];tile2=H_Flip[tile2];}
1670
1671 tilepix=((uint)(tile2&0xAA)<<8)|((uint)(tile1&0xAA)<<7)|
1672 (tile1&0x55)|((tile2&0x55)<<1);
1673
1674 FPAL[0]=(uchar)BGPAL[tile_a&7][0];
1675 FPAL[1]=(uchar)BGPAL[tile_a&7][1];
1676 FPAL[2]=(uchar)BGPAL[tile_a&7][2];
1677 FPAL[3]=(uchar)BGPAL[tile_a&7][3];
1678
1679 do_tilepix(uchar, 2);
1680 }
1681 }
1682
1683 if (LCDC & 0x02) { /* sprites enabled */
1684 ty=LCDC & 0x04 ? 16 : 8;
1685
1686 y=LY*GB_XBUFFERSIZE;
1687 if (doublesize) y<<=2;
1688
1689 /* background sprites */
1690 for (xc=GB_SPRITECOUNT-1,sprofs=oam+0x9C;xc>=0;xc--,sprofs-=4) {
1691 tmp=LY-sprofs[0]+16;
1692 if ((sprofs[3]&0x80)&&(tmp>=0)&&(tmp<ty)&&
1693 (sprofs[1]<GB_LCDXSCREENSIZE+8)) {
1694 if (sprofs[3]&0x40) tmp=ty-1-tmp;
1695 tiledata=vram[(sprofs[3]>>3)&1]
1696 +(((uint)(sprofs[2] & (LCDC & 0x04 ? 0xFE : 0xFF)))<<4)
1697 +(tmp<<1);
1698 if (sprofs[3]&0x20) {
1699 tile1=H_Flip[tiledata[0]];
1700 tile2=H_Flip[tiledata[1]];
1701 } else {
1702 tile1=tiledata[0];
1703 tile2=tiledata[1];
1704 }
1705 tilepix=((uint)(tile2&0xAA)<<8)|((uint)(tile1&0xAA)<<7)|
1706 (tile1&0x55)|((tile2&0x55)<<1);
1707 x=sprofs[1];
1708
1709 FPAL[0]=(uchar)OBJPAL[sprofs[3]&7][0];
1710 FPAL[1]=(uchar)OBJPAL[sprofs[3]&7][1];
1711 FPAL[2]=(uchar)OBJPAL[sprofs[3]&7][2];
1712 FPAL[3]=(uchar)OBJPAL[sprofs[3]&7][3];
1713
1714 if (!doublesize) {
1715 if ((zbuffer[x]==0)&&(tilepix>>14))
1716 ((uchar *)lcdbuffer)[y+x]=FPAL[tilepix >> 14];
1717 if ((zbuffer[x+1]==0)&&((tilepix>>6)&0x03))
1718 ((uchar *)lcdbuffer)[y+x+1]=FPAL[(tilepix >> 6)&0x03];
1719 if ((zbuffer[x+2]==0)&&((tilepix>>12)&0x03))
1720 ((uchar *)lcdbuffer)[y+x+2]=FPAL[(tilepix >> 12)&0x03];
1721 if ((zbuffer[x+3]==0)&&((tilepix>>4)&0x03))
1722 ((uchar *)lcdbuffer)[y+x+3]=FPAL[(tilepix >> 4)&0x03];
1723 if ((zbuffer[x+4]==0)&&((tilepix>>10)&0x03))
1724 ((uchar *)lcdbuffer)[y+x+4]=FPAL[(tilepix >> 10)&0x03];
1725 if ((zbuffer[x+5]==0)&&((tilepix>>2)&0x03))
1726 ((uchar *)lcdbuffer)[y+x+5]=FPAL[(tilepix >> 2)&0x03];
1727 if ((zbuffer[x+6]==0)&&((tilepix>>8)&0x03))
1728 ((uchar *)lcdbuffer)[y+x+6]=FPAL[(tilepix >> 8)&0x03];
1729 if ((zbuffer[x+7]==0)&&(tilepix&0x03))
1730 ((uchar *)lcdbuffer)[y+x+7]=FPAL[tilepix&0x03];
1731 } else {
1732 if ((zbuffer[x]==0)&&(tilepix>>14))
1733 ((uchar *)lcdbuffer)[y+(x<<1) ]=
1734 ((uchar *)lcdbuffer)[y+(x<<1)+1]=FPAL[tilepix >> 14];
1735 if ((zbuffer[x+1]==0)&&((tilepix>>6)&0x03))
1736 ((uchar *)lcdbuffer)[y+(x<<1)+2]=
1737 ((uchar *)lcdbuffer)[y+(x<<1)+3]=FPAL[(tilepix >> 6)&0x03];
1738 if ((zbuffer[x+2]==0)&&((tilepix>>12)&0x03))
1739 ((uchar *)lcdbuffer)[y+(x<<1)+4]=
1740 ((uchar *)lcdbuffer)[y+(x<<1)+5]=FPAL[(tilepix >> 12)&0x03];
1741 if ((zbuffer[x+3]==0)&&((tilepix>>4)&0x03))
1742 ((uchar *)lcdbuffer)[y+(x<<1)+6]=
1743 ((uchar *)lcdbuffer)[y+(x<<1)+7]=FPAL[(tilepix >> 4)&0x03];
1744 if ((zbuffer[x+4]==0)&&((tilepix>>10)&0x03))
1745 ((uchar *)lcdbuffer)[y+(x<<1)+8]=
1746 ((uchar *)lcdbuffer)[y+(x<<1)+9]=FPAL[(tilepix >> 10)&0x03];
1747 if ((zbuffer[x+5]==0)&&((tilepix>>2)&0x03))
1748 ((uchar *)lcdbuffer)[y+(x<<1)+10]=
1749 ((uchar *)lcdbuffer)[y+(x<<1)+11]=FPAL[(tilepix >> 2)&0x03];
1750 if ((zbuffer[x+6]==0)&&((tilepix>>8)&0x03))
1751 ((uchar *)lcdbuffer)[y+(x<<1)+12]=
1752 ((uchar *)lcdbuffer)[y+(x<<1)+13]=FPAL[(tilepix >> 8)&0x03];
1753 if ((zbuffer[x+7]==0)&&(tilepix&0x03))
1754 ((uchar *)lcdbuffer)[y+(x<<1)+14]=
1755 ((uchar *)lcdbuffer)[y+(x<<1)+15]=FPAL[tilepix&0x03];
1756 }
1757 }
1758 }
1759
1760 /* foreground sprites */
1761 for (xc=GB_SPRITECOUNT-1,sprofs=oam+0x9C;xc>=0;xc--,sprofs-=4) {
1762 tmp=LY-sprofs[0]+16;
1763 if (((sprofs[3]&0x80)==0)&&(tmp>=0)&&(tmp<ty)&&
1764 (sprofs[1]<GB_LCDXSCREENSIZE+8)) {
1765 if (sprofs[3]&0x40) tmp=ty-1-tmp;
1766 tiledata=vram[(sprofs[3]>>3)&1]
1767 +(((uint)(sprofs[2] & (LCDC & 0x04 ? 0xFE : 0xFF)))<<4)
1768 +(tmp<<1);
1769 if (sprofs[3]&0x20) {
1770 tile1=H_Flip[tiledata[0]];
1771 tile2=H_Flip[tiledata[1]];
1772 } else {
1773 tile1=tiledata[0];
1774 tile2=tiledata[1];
1775 }
1776 tilepix=((uint)(tile2&0xAA)<<8)|((uint)(tile1&0xAA)<<7)|
1777 (tile1&0x55)|((tile2&0x55)<<1);
1778 x=sprofs[1];
1779
1780 FPAL[0]=(uchar)OBJPAL[sprofs[3]&7][0];
1781 FPAL[1]=(uchar)OBJPAL[sprofs[3]&7][1];
1782 FPAL[2]=(uchar)OBJPAL[sprofs[3]&7][2];
1783 FPAL[3]=(uchar)OBJPAL[sprofs[3]&7][3];
1784
1785 if (!doublesize) {
1786 if (tilepix>>14)
1787 ((uchar *)lcdbuffer)[y+x]=FPAL[tilepix >> 14];
1788 if ((tilepix>>6)&0x03)
1789 ((uchar *)lcdbuffer)[y+x+1]=FPAL[(tilepix >> 6)&0x03];
1790 if ((tilepix>>12)&0x03)
1791 ((uchar *)lcdbuffer)[y+x+2]=FPAL[(tilepix >> 12)&0x03];
1792 if ((tilepix>>4)&0x03)
1793 ((uchar *)lcdbuffer)[y+x+3]=FPAL[(tilepix >> 4)&0x03];
1794 if ((tilepix>>10)&0x03)
1795 ((uchar *)lcdbuffer)[y+x+4]=FPAL[(tilepix >> 10)&0x03];
1796 if ((tilepix>>2)&0x03)
1797 ((uchar *)lcdbuffer)[y+x+5]=FPAL[(tilepix >> 2)&0x03];
1798 if ((tilepix>>8)&0x03)
1799 ((uchar *)lcdbuffer)[y+x+6]=FPAL[(tilepix >> 8)&0x03];
1800 if (tilepix&0x03)
1801 ((uchar *)lcdbuffer)[y+x+7]=FPAL[tilepix&0x03];
1802 } else {
1803 if (tilepix>>14)
1804 ((uchar *)lcdbuffer)[y+(x<<1) ]=
1805 ((uchar *)lcdbuffer)[y+(x<<1)+1]=FPAL[tilepix >> 14];
1806 if ((tilepix>>6)&0x03)
1807 ((uchar *)lcdbuffer)[y+(x<<1)+2]=
1808 ((uchar *)lcdbuffer)[y+(x<<1)+3]=FPAL[(tilepix >> 6)&0x03];
1809 if ((tilepix>>12)&0x03)
1810 ((uchar *)lcdbuffer)[y+(x<<1)+4]=
1811 ((uchar *)lcdbuffer)[y+(x<<1)+5]=FPAL[(tilepix >> 12)&0x03];
1812 if ((tilepix>>4)&0x03)
1813 ((uchar *)lcdbuffer)[y+(x<<1)+6]=
1814 ((uchar *)lcdbuffer)[y+(x<<1)+7]=FPAL[(tilepix >> 4)&0x03];
1815 if ((tilepix>>10)&0x03)
1816 ((uchar *)lcdbuffer)[y+(x<<1)+8]=
1817 ((uchar *)lcdbuffer)[y+(x<<1)+9]=FPAL[(tilepix >> 10)&0x03];
1818 if ((tilepix>>2)&0x03)
1819 ((uchar *)lcdbuffer)[y+(x<<1)+10]=
1820 ((uchar *)lcdbuffer)[y+(x<<1)+11]=FPAL[(tilepix >> 2)&0x03];
1821 if ((tilepix>>8)&0x03)
1822 ((uchar *)lcdbuffer)[y+(x<<1)+12]=
1823 ((uchar *)lcdbuffer)[y+(x<<1)+13]=FPAL[(tilepix >> 8)&0x03];
1824 if (tilepix&0x03)
1825 ((uchar *)lcdbuffer)[y+(x<<1)+14]=
1826 ((uchar *)lcdbuffer)[y+(x<<1)+15]=FPAL[tilepix&0x03];
1827 }
1828 }
1829 }
1830
1831
1832 }
1833 }
1834
gb_scanline16(void)1835 void gb_scanline16(void)
1836 {
1837 int x,y,tx,ty,xc,tmp;
1838 uchar *tileofs,*tiledata,*sprofs;
1839 uchar tile,tile1,tile2;
1840 uint tilepix;
1841 uchar zbuffer[GB_XBUFFERSIZE];
1842 uint FPAL[4];
1843
1844 FPAL[0]=GB_STDPAL[BGP & 0x03];
1845 FPAL[1]=GB_STDPAL[(BGP >> 2)& 0x03];
1846 FPAL[2]=GB_STDPAL[(BGP >> 4)& 0x03];
1847 FPAL[3]=GB_STDPAL[BGP >> 6];
1848
1849
1850 y=LY*GB_XBUFFERSIZE;
1851 if (doublesize) y<<=2;
1852
1853 if (LCDC & 0x01) { /* if BG enabled */
1854 tileofs=vram[0]
1855 +((((LY+SCY)&0xFF) >> 3)<<5)+(LCDC & 0x08 ? 0x1C00 : 0x1800);
1856 xc=((LCDC & 0x20)&&(WY<=LY) ? ((WX<7 ? 0 : WX-7) >> 3) : 21);
1857 xc=xc>21 ? 21 : xc;
1858 for (tx=0,x=8-(SCX & 7);tx<xc;tx++,x+=8) {
1859 tile=tileofs[(tx+(SCX>>3))&0x1F];
1860 tiledata=LCDC & 0x10 ? vram[0]+((int)tile<<4)
1861 : vram[0]+0x1000+((int)((signed char)tile)<<4);
1862 tiledata+=((LY+SCY)&7)<<1;
1863 tilepix=((uint)(tiledata[1]&0xAA)<<8)|((uint)(tiledata[0]&0xAA)<<7)|
1864 (tiledata[0]&0x55)|((tiledata[1]&0x55)<<1);
1865
1866 do_tilepix(uint, 2);
1867 }
1868 } else { /* if BG not enabled */
1869
1870 uint *p;
1871
1872 memset(zbuffer,0,GB_XBUFFERSIZE);
1873
1874 p=(uint *)lcdbuffer+y;
1875 if (doublesize)
1876 for (x=0;x<GB_XBUFFERSIZE*2;x++) *p++=FPAL[0];
1877 else
1878 for (x=0;x<GB_XBUFFERSIZE;x++) *p++=FPAL[0];
1879 }
1880
1881 if ((LCDC & 0x20)&&(WY<=LY)&&(WX<167)) { /* if window is on and visible */
1882
1883 y=LY*GB_XBUFFERSIZE;
1884 if (doublesize) y<<=2;
1885
1886 x=WX+1;xc=167-WX;
1887 tileofs=vram[0]+(((LY-WY) >> 3)<<5)+(LCDC & 0x40 ? 0x1C00 : 0x1800);
1888 for (tx=0;xc>0;xc-=8,x+=8,tx++) {
1889 tiledata=LCDC & 0x10 ? vram[0]+((int)tileofs[tx]<<4)
1890 : vram[0]+0x1000+((int)((signed char)tileofs[tx])<<4);
1891 tiledata+=((LY-WY)&7)<<1;
1892 tilepix=((uint)(tiledata[1]&0xAA)<<8)|((uint)(tiledata[0]&0xAA)<<7)|
1893 (tiledata[0]&0x55)|((tiledata[1]&0x55)<<1);
1894
1895 do_tilepix(uint, 2);
1896 }
1897 }
1898
1899 if (LCDC & 0x02) { /* sprites enabled */
1900 ty=LCDC & 0x04 ? 16 : 8;
1901
1902 y=LY*GB_XBUFFERSIZE;
1903 if (doublesize) y<<=2;
1904
1905 /* background sprites */
1906 for (xc=GB_SPRITECOUNT-1,sprofs=oam+0x9C;xc>=0;xc--,sprofs-=4) {
1907 tmp=LY-sprofs[0]+16;
1908 if ((sprofs[3]&0x80)&&(tmp>=0)&&(tmp<ty)&&
1909 (sprofs[1]<GB_LCDXSCREENSIZE+8)) {
1910 if (sprofs[3]&0x40) tmp=ty-1-tmp;
1911 tiledata=vram[0]
1912 +(((uint)(sprofs[2] & (LCDC & 0x04 ? 0xFE : 0xFF)))<<4)
1913 +(tmp<<1);
1914 if (sprofs[3]&0x20) {
1915 tile1=H_Flip[tiledata[0]];
1916 tile2=H_Flip[tiledata[1]];
1917 } else {
1918 tile1=tiledata[0];
1919 tile2=tiledata[1];
1920 }
1921 tilepix=((uint)(tile2&0xAA)<<8)|((uint)(tile1&0xAA)<<7)|
1922 (tile1&0x55)|((tile2&0x55)<<1);
1923 x=sprofs[1];
1924
1925 if (sprofs[3]&0x10) {
1926 FPAL[0]=GB_STDPAL[OBP1 & 0x03];
1927 FPAL[1]=GB_STDPAL[(OBP1 >> 2)& 0x03];
1928 FPAL[2]=GB_STDPAL[(OBP1 >> 4)& 0x03];
1929 FPAL[3]=GB_STDPAL[OBP1 >> 6];
1930 } else {
1931 FPAL[0]=GB_STDPAL[OBP0 & 0x03];
1932 FPAL[1]=GB_STDPAL[(OBP0 >> 2)& 0x03];
1933 FPAL[2]=GB_STDPAL[(OBP0 >> 4)& 0x03];
1934 FPAL[3]=GB_STDPAL[OBP0 >> 6];
1935 }
1936
1937 if (!doublesize) {
1938 if ((zbuffer[x]==0)&&(tilepix>>14))
1939 ((uint *)lcdbuffer)[y+x]=FPAL[tilepix >> 14];
1940 if ((zbuffer[x+1]==0)&&((tilepix>>6)&0x03))
1941 ((uint *)lcdbuffer)[y+x+1]=FPAL[(tilepix >> 6)&0x03];
1942 if ((zbuffer[x+2]==0)&&((tilepix>>12)&0x03))
1943 ((uint *)lcdbuffer)[y+x+2]=FPAL[(tilepix >> 12)&0x03];
1944 if ((zbuffer[x+3]==0)&&((tilepix>>4)&0x03))
1945 ((uint *)lcdbuffer)[y+x+3]=FPAL[(tilepix >> 4)&0x03];
1946 if ((zbuffer[x+4]==0)&&((tilepix>>10)&0x03))
1947 ((uint *)lcdbuffer)[y+x+4]=FPAL[(tilepix >> 10)&0x03];
1948 if ((zbuffer[x+5]==0)&&((tilepix>>2)&0x03))
1949 ((uint *)lcdbuffer)[y+x+5]=FPAL[(tilepix >> 2)&0x03];
1950 if ((zbuffer[x+6]==0)&&((tilepix>>8)&0x03))
1951 ((uint *)lcdbuffer)[y+x+6]=FPAL[(tilepix >> 8)&0x03];
1952 if ((zbuffer[x+7]==0)&&(tilepix&0x03))
1953 ((uint *)lcdbuffer)[y+x+7]=FPAL[tilepix&0x03];
1954 } else {
1955 if ((zbuffer[x]==0)&&(tilepix>>14))
1956 ((uint *)lcdbuffer)[y+(x<<1) ]=
1957 ((uint *)lcdbuffer)[y+(x<<1)+1]=FPAL[tilepix >> 14];
1958 if ((zbuffer[x+1]==0)&&((tilepix>>6)&0x03))
1959 ((uint *)lcdbuffer)[y+(x<<1)+2]=
1960 ((uint *)lcdbuffer)[y+(x<<1)+3]=FPAL[(tilepix >> 6)&0x03];
1961 if ((zbuffer[x+2]==0)&&((tilepix>>12)&0x03))
1962 ((uint *)lcdbuffer)[y+(x<<1)+4]=
1963 ((uint *)lcdbuffer)[y+(x<<1)+5]=FPAL[(tilepix >> 12)&0x03];
1964 if ((zbuffer[x+3]==0)&&((tilepix>>4)&0x03))
1965 ((uint *)lcdbuffer)[y+(x<<1)+6]=
1966 ((uint *)lcdbuffer)[y+(x<<1)+7]=FPAL[(tilepix >> 4)&0x03];
1967 if ((zbuffer[x+4]==0)&&((tilepix>>10)&0x03))
1968 ((uint *)lcdbuffer)[y+(x<<1)+8]=
1969 ((uint *)lcdbuffer)[y+(x<<1)+9]=FPAL[(tilepix >> 10)&0x03];
1970 if ((zbuffer[x+5]==0)&&((tilepix>>2)&0x03))
1971 ((uint *)lcdbuffer)[y+(x<<1)+10]=
1972 ((uint *)lcdbuffer)[y+(x<<1)+11]=FPAL[(tilepix >> 2)&0x03];
1973 if ((zbuffer[x+6]==0)&&((tilepix>>8)&0x03))
1974 ((uint *)lcdbuffer)[y+(x<<1)+12]=
1975 ((uint *)lcdbuffer)[y+(x<<1)+13]=FPAL[(tilepix >> 8)&0x03];
1976 if ((zbuffer[x+7]==0)&&(tilepix&0x03))
1977 ((uint *)lcdbuffer)[y+(x<<1)+14]=
1978 ((uint *)lcdbuffer)[y+(x<<1)+15]=FPAL[tilepix&0x03];
1979 }
1980 }
1981 }
1982
1983 /* foreground sprites */
1984 for (xc=GB_SPRITECOUNT-1,sprofs=oam+0x9C;xc>=0;xc--,sprofs-=4) {
1985 tmp=LY-sprofs[0]+16;
1986 if (((sprofs[3]&0x80)==0)&&(tmp>=0)&&(tmp<ty)&&
1987 (sprofs[1]<GB_LCDXSCREENSIZE+8)) {
1988 if (sprofs[3]&0x40) tmp=ty-1-tmp;
1989 tiledata=vram[0]
1990 +(((uint)(sprofs[2] & (LCDC & 0x04 ? 0xFE : 0xFF)))<<4)
1991 +(tmp<<1);
1992 if (sprofs[3]&0x20) {
1993 tile1=H_Flip[tiledata[0]];
1994 tile2=H_Flip[tiledata[1]];
1995 } else {
1996 tile1=tiledata[0];
1997 tile2=tiledata[1];
1998 }
1999 tilepix=((uint)(tile2&0xAA)<<8)|((uint)(tile1&0xAA)<<7)|
2000 (tile1&0x55)|((tile2&0x55)<<1);
2001 x=sprofs[1];
2002
2003 if (sprofs[3]&0x10) {
2004 FPAL[0]=GB_STDPAL[OBP1 & 0x03];
2005 FPAL[1]=GB_STDPAL[(OBP1 >> 2)& 0x03];
2006 FPAL[2]=GB_STDPAL[(OBP1 >> 4)& 0x03];
2007 FPAL[3]=GB_STDPAL[OBP1 >> 6];
2008 } else {
2009 FPAL[0]=GB_STDPAL[OBP0 & 0x03];
2010 FPAL[1]=GB_STDPAL[(OBP0 >> 2)& 0x03];
2011 FPAL[2]=GB_STDPAL[(OBP0 >> 4)& 0x03];
2012 FPAL[3]=GB_STDPAL[OBP0 >> 6];
2013 }
2014
2015 if (!doublesize) {
2016 if (tilepix>>14)
2017 ((uint *)lcdbuffer)[y+x]=FPAL[tilepix >> 14];
2018 if ((tilepix>>6)&0x03)
2019 ((uint *)lcdbuffer)[y+x+1]=FPAL[(tilepix >> 6)&0x03];
2020 if ((tilepix>>12)&0x03)
2021 ((uint *)lcdbuffer)[y+x+2]=FPAL[(tilepix >> 12)&0x03];
2022 if ((tilepix>>4)&0x03)
2023 ((uint *)lcdbuffer)[y+x+3]=FPAL[(tilepix >> 4)&0x03];
2024 if ((tilepix>>10)&0x03)
2025 ((uint *)lcdbuffer)[y+x+4]=FPAL[(tilepix >> 10)&0x03];
2026 if ((tilepix>>2)&0x03)
2027 ((uint *)lcdbuffer)[y+x+5]=FPAL[(tilepix >> 2)&0x03];
2028 if ((tilepix>>8)&0x03)
2029 ((uint *)lcdbuffer)[y+x+6]=FPAL[(tilepix >> 8)&0x03];
2030 if (tilepix&0x03)
2031 ((uint *)lcdbuffer)[y+x+7]=FPAL[tilepix&0x03];
2032 } else {
2033 if (tilepix>>14)
2034 ((uint *)lcdbuffer)[y+(x<<1) ]=
2035 ((uint *)lcdbuffer)[y+(x<<1)+1]=FPAL[tilepix >> 14];
2036 if ((tilepix>>6)&0x03)
2037 ((uint *)lcdbuffer)[y+(x<<1)+2]=
2038 ((uint *)lcdbuffer)[y+(x<<1)+3]=FPAL[(tilepix >> 6)&0x03];
2039 if ((tilepix>>12)&0x03)
2040 ((uint *)lcdbuffer)[y+(x<<1)+4]=
2041 ((uint *)lcdbuffer)[y+(x<<1)+5]=FPAL[(tilepix >> 12)&0x03];
2042 if ((tilepix>>4)&0x03)
2043 ((uint *)lcdbuffer)[y+(x<<1)+6]=
2044 ((uint *)lcdbuffer)[y+(x<<1)+7]=FPAL[(tilepix >> 4)&0x03];
2045 if ((tilepix>>10)&0x03)
2046 ((uint *)lcdbuffer)[y+(x<<1)+8]=
2047 ((uint *)lcdbuffer)[y+(x<<1)+9]=FPAL[(tilepix >> 10)&0x03];
2048 if ((tilepix>>2)&0x03)
2049 ((uint *)lcdbuffer)[y+(x<<1)+10]=
2050 ((uint *)lcdbuffer)[y+(x<<1)+11]=FPAL[(tilepix >> 2)&0x03];
2051 if ((tilepix>>8)&0x03)
2052 ((uint *)lcdbuffer)[y+(x<<1)+12]=
2053 ((uint *)lcdbuffer)[y+(x<<1)+13]=FPAL[(tilepix >> 8)&0x03];
2054 if (tilepix&0x03)
2055 ((uint *)lcdbuffer)[y+(x<<1)+14]=
2056 ((uint *)lcdbuffer)[y+(x<<1)+15]=FPAL[tilepix&0x03];
2057 }
2058 }
2059 }
2060
2061
2062 }
2063 }
2064
cgb_scanline16(void)2065 void cgb_scanline16(void)
2066 {
2067 int x,y,tx,ty,xc,tmp;
2068 uchar *tileofs1,*tileofs2,*tiledata,*sprofs;
2069 uchar tile,tile1,tile2,tile_a;
2070 uint tilepix,tilenum;
2071 uchar zbuffer[GB_XBUFFERSIZE];
2072 uint FPAL[4];
2073
2074 y=LY*GB_XBUFFERSIZE;
2075 if (doublesize) y<<=2;
2076
2077 if (LCDC & 0x01) { /* if BG enabled */
2078 tilenum=((((LY+SCY)&0xFF) >> 3)<<5)+(LCDC & 0x08 ? 0x1C00 : 0x1800);
2079 tileofs1=vram[0]+tilenum;
2080 tileofs2=vram[1]+tilenum;
2081 xc=((LCDC & 0x20)&&(WY<=LY) ? ((WX<7 ? 0 : WX-7) >> 3) : 21);
2082 xc=xc>21 ? 21 : xc;
2083 for (tx=0,x=8-(SCX & 7);tx<xc;tx++,x+=8) {
2084 tile=tileofs1[(tx+(SCX>>3))&0x1F];
2085 tile_a=tileofs2[(tx+(SCX>>3))&0x1F];
2086 tiledata=LCDC & 0x10 ? vram[(tile_a>>3)&1]+((int)tile<<4)
2087 : vram[(tile_a>>3)&1]+0x1000+((int)((signed char)tile)<<4);
2088 tiledata+=(tile_a&0x40) ? (7-((LY+SCY)&7))<<1:((LY+SCY)&7)<<1;
2089 tile1=tiledata[0];tile2=tiledata[1];
2090 if (tile_a&0x20) {tile1=H_Flip[tile1];tile2=H_Flip[tile2];}
2091
2092 tilepix=((uint)(tile2&0xAA)<<8)|((uint)(tile1&0xAA)<<7)|
2093 (tile1&0x55)|((tile2&0x55)<<1);
2094
2095 FPAL[0]=BGPAL[tile_a&7][0];
2096 FPAL[1]=BGPAL[tile_a&7][1];
2097 FPAL[2]=BGPAL[tile_a&7][2];
2098 FPAL[3]=BGPAL[tile_a&7][3];
2099
2100 do_tilepix(uint, 2);
2101 }
2102 } else { /* if BG not enabled */
2103 uint *p;
2104
2105 memset(zbuffer,0,GB_XBUFFERSIZE);
2106
2107 p=(uint *)lcdbuffer+y;
2108 if (doublesize)
2109 for (x=0;x<GB_XBUFFERSIZE*2;x++) *p++=0; /* 0 or background ? */
2110 else
2111 for (x=0;x<GB_XBUFFERSIZE;x++) *p++=0; /* 0 or background ? */
2112
2113 }
2114
2115 if ((LCDC & 0x20)&&(WY<=LY)&&(WX<167)) { /* if window is on and visible */
2116
2117 y=LY*GB_XBUFFERSIZE;
2118 if (doublesize) y<<=2;
2119
2120 x=WX+1;xc=167-WX;
2121 tilenum=(((LY-WY) >> 3)<<5)+(LCDC & 0x40 ? 0x1C00 : 0x1800);
2122 tileofs1=vram[0]+tilenum;
2123 tileofs2=vram[1]+tilenum;
2124 for (tx=0;xc>0;xc-=8,x+=8,tx++) {
2125 tile_a=tileofs2[tx];
2126 tiledata=LCDC & 0x10 ? vram[(tile_a>>3)&1]+((int)tileofs1[tx]<<4)
2127 : vram[(tile_a>>3)&1]+0x1000+((int)((signed char)tileofs1[tx])<<4);
2128
2129 tiledata+=(tile_a&0x40) ? (7-((LY-WY)&7))<<1:((LY-WY)&7)<<1;
2130 tile1=tiledata[0];tile2=tiledata[1];
2131 if (tile_a&0x20) {tile1=H_Flip[tile1];tile2=H_Flip[tile2];}
2132
2133 tilepix=((uint)(tile2&0xAA)<<8)|((uint)(tile1&0xAA)<<7)|
2134 (tile1&0x55)|((tile2&0x55)<<1);
2135
2136 FPAL[0]=BGPAL[tile_a&7][0];
2137 FPAL[1]=BGPAL[tile_a&7][1];
2138 FPAL[2]=BGPAL[tile_a&7][2];
2139 FPAL[3]=BGPAL[tile_a&7][3];
2140
2141 do_tilepix(uint, 2);
2142 }
2143 }
2144
2145 if (LCDC & 0x02) { /* sprites enabled */
2146 ty=LCDC & 0x04 ? 16 : 8;
2147
2148 y=LY*GB_XBUFFERSIZE;
2149 if (doublesize) y<<=2;
2150
2151 /* background sprites */
2152 for (xc=GB_SPRITECOUNT-1,sprofs=oam+0x9C;xc>=0;xc--,sprofs-=4) {
2153 tmp=LY-sprofs[0]+16;
2154 if ((sprofs[3]&0x80)&&(tmp>=0)&&(tmp<ty)&&
2155 (sprofs[1]<GB_LCDXSCREENSIZE+8)) {
2156 if (sprofs[3]&0x40) tmp=ty-1-tmp;
2157 tiledata=vram[(sprofs[3]>>3)&1]
2158 +(((uint)(sprofs[2] & (LCDC & 0x04 ? 0xFE : 0xFF)))<<4)
2159 +(tmp<<1);
2160 if (sprofs[3]&0x20) {
2161 tile1=H_Flip[tiledata[0]];
2162 tile2=H_Flip[tiledata[1]];
2163 } else {
2164 tile1=tiledata[0];
2165 tile2=tiledata[1];
2166 }
2167 tilepix=((uint)(tile2&0xAA)<<8)|((uint)(tile1&0xAA)<<7)|
2168 (tile1&0x55)|((tile2&0x55)<<1);
2169 x=sprofs[1];
2170
2171 FPAL[0]=OBJPAL[sprofs[3]&7][0];
2172 FPAL[1]=OBJPAL[sprofs[3]&7][1];
2173 FPAL[2]=OBJPAL[sprofs[3]&7][2];
2174 FPAL[3]=OBJPAL[sprofs[3]&7][3];
2175
2176 if (!doublesize) {
2177 if ((zbuffer[x]==0)&&(tilepix>>14))
2178 ((uint *)lcdbuffer)[y+x]=FPAL[tilepix >> 14];
2179 if ((zbuffer[x+1]==0)&&((tilepix>>6)&0x03))
2180 ((uint *)lcdbuffer)[y+x+1]=FPAL[(tilepix >> 6)&0x03];
2181 if ((zbuffer[x+2]==0)&&((tilepix>>12)&0x03))
2182 ((uint *)lcdbuffer)[y+x+2]=FPAL[(tilepix >> 12)&0x03];
2183 if ((zbuffer[x+3]==0)&&((tilepix>>4)&0x03))
2184 ((uint *)lcdbuffer)[y+x+3]=FPAL[(tilepix >> 4)&0x03];
2185 if ((zbuffer[x+4]==0)&&((tilepix>>10)&0x03))
2186 ((uint *)lcdbuffer)[y+x+4]=FPAL[(tilepix >> 10)&0x03];
2187 if ((zbuffer[x+5]==0)&&((tilepix>>2)&0x03))
2188 ((uint *)lcdbuffer)[y+x+5]=FPAL[(tilepix >> 2)&0x03];
2189 if ((zbuffer[x+6]==0)&&((tilepix>>8)&0x03))
2190 ((uint *)lcdbuffer)[y+x+6]=FPAL[(tilepix >> 8)&0x03];
2191 if ((zbuffer[x+7]==0)&&(tilepix&0x03))
2192 ((uint *)lcdbuffer)[y+x+7]=FPAL[tilepix&0x03];
2193 } else {
2194 if ((zbuffer[x]==0)&&(tilepix>>14))
2195 ((uint *)lcdbuffer)[y+(x<<1) ]=
2196 ((uint *)lcdbuffer)[y+(x<<1)+1]=FPAL[tilepix >> 14];
2197 if ((zbuffer[x+1]==0)&&((tilepix>>6)&0x03))
2198 ((uint *)lcdbuffer)[y+(x<<1)+2]=
2199 ((uint *)lcdbuffer)[y+(x<<1)+3]=FPAL[(tilepix >> 6)&0x03];
2200 if ((zbuffer[x+2]==0)&&((tilepix>>12)&0x03))
2201 ((uint *)lcdbuffer)[y+(x<<1)+4]=
2202 ((uint *)lcdbuffer)[y+(x<<1)+5]=FPAL[(tilepix >> 12)&0x03];
2203 if ((zbuffer[x+3]==0)&&((tilepix>>4)&0x03))
2204 ((uint *)lcdbuffer)[y+(x<<1)+6]=
2205 ((uint *)lcdbuffer)[y+(x<<1)+7]=FPAL[(tilepix >> 4)&0x03];
2206 if ((zbuffer[x+4]==0)&&((tilepix>>10)&0x03))
2207 ((uint *)lcdbuffer)[y+(x<<1)+8]=
2208 ((uint *)lcdbuffer)[y+(x<<1)+9]=FPAL[(tilepix >> 10)&0x03];
2209 if ((zbuffer[x+5]==0)&&((tilepix>>2)&0x03))
2210 ((uint *)lcdbuffer)[y+(x<<1)+10]=
2211 ((uint *)lcdbuffer)[y+(x<<1)+11]=FPAL[(tilepix >> 2)&0x03];
2212 if ((zbuffer[x+6]==0)&&((tilepix>>8)&0x03))
2213 ((uint *)lcdbuffer)[y+(x<<1)+12]=
2214 ((uint *)lcdbuffer)[y+(x<<1)+13]=FPAL[(tilepix >> 8)&0x03];
2215 if ((zbuffer[x+7]==0)&&(tilepix&0x03))
2216 ((uint *)lcdbuffer)[y+(x<<1)+14]=
2217 ((uint *)lcdbuffer)[y+(x<<1)+15]=FPAL[tilepix&0x03];
2218 }
2219 }
2220 }
2221
2222 /* foreground sprites */
2223 for (xc=GB_SPRITECOUNT-1,sprofs=oam+0x9C;xc>=0;xc--,sprofs-=4) {
2224 tmp=LY-sprofs[0]+16;
2225 if (((sprofs[3]&0x80)==0)&&(tmp>=0)&&(tmp<ty)&&
2226 (sprofs[1]<GB_LCDXSCREENSIZE+8)) {
2227 if (sprofs[3]&0x40) tmp=ty-1-tmp;
2228 tiledata=vram[(sprofs[3]>>3)&1]
2229 +(((uint)(sprofs[2] & (LCDC & 0x04 ? 0xFE : 0xFF)))<<4)
2230 +(tmp<<1);
2231 if (sprofs[3]&0x20) {
2232 tile1=H_Flip[tiledata[0]];
2233 tile2=H_Flip[tiledata[1]];
2234 } else {
2235 tile1=tiledata[0];
2236 tile2=tiledata[1];
2237 }
2238 tilepix=((uint)(tile2&0xAA)<<8)|((uint)(tile1&0xAA)<<7)|
2239 (tile1&0x55)|((tile2&0x55)<<1);
2240 x=sprofs[1];
2241
2242 FPAL[0]=OBJPAL[sprofs[3]&7][0];
2243 FPAL[1]=OBJPAL[sprofs[3]&7][1];
2244 FPAL[2]=OBJPAL[sprofs[3]&7][2];
2245 FPAL[3]=OBJPAL[sprofs[3]&7][3];
2246
2247 if (!doublesize) {
2248 if (tilepix>>14)
2249 ((uint *)lcdbuffer)[y+x]=FPAL[tilepix >> 14];
2250 if ((tilepix>>6)&0x03)
2251 ((uint *)lcdbuffer)[y+x+1]=FPAL[(tilepix >> 6)&0x03];
2252 if ((tilepix>>12)&0x03)
2253 ((uint *)lcdbuffer)[y+x+2]=FPAL[(tilepix >> 12)&0x03];
2254 if ((tilepix>>4)&0x03)
2255 ((uint *)lcdbuffer)[y+x+3]=FPAL[(tilepix >> 4)&0x03];
2256 if ((tilepix>>10)&0x03)
2257 ((uint *)lcdbuffer)[y+x+4]=FPAL[(tilepix >> 10)&0x03];
2258 if ((tilepix>>2)&0x03)
2259 ((uint *)lcdbuffer)[y+x+5]=FPAL[(tilepix >> 2)&0x03];
2260 if ((tilepix>>8)&0x03)
2261 ((uint *)lcdbuffer)[y+x+6]=FPAL[(tilepix >> 8)&0x03];
2262 if (tilepix&0x03)
2263 ((uint *)lcdbuffer)[y+x+7]=FPAL[tilepix&0x03];
2264 } else {
2265 if (tilepix>>14)
2266 ((uint *)lcdbuffer)[y+(x<<1) ]=
2267 ((uint *)lcdbuffer)[y+(x<<1)+1]=FPAL[tilepix >> 14];
2268 if ((tilepix>>6)&0x03)
2269 ((uint *)lcdbuffer)[y+(x<<1)+2]=
2270 ((uint *)lcdbuffer)[y+(x<<1)+3]=FPAL[(tilepix >> 6)&0x03];
2271 if ((tilepix>>12)&0x03)
2272 ((uint *)lcdbuffer)[y+(x<<1)+4]=
2273 ((uint *)lcdbuffer)[y+(x<<1)+5]=FPAL[(tilepix >> 12)&0x03];
2274 if ((tilepix>>4)&0x03)
2275 ((uint *)lcdbuffer)[y+(x<<1)+6]=
2276 ((uint *)lcdbuffer)[y+(x<<1)+7]=FPAL[(tilepix >> 4)&0x03];
2277 if ((tilepix>>10)&0x03)
2278 ((uint *)lcdbuffer)[y+(x<<1)+8]=
2279 ((uint *)lcdbuffer)[y+(x<<1)+9]=FPAL[(tilepix >> 10)&0x03];
2280 if ((tilepix>>2)&0x03)
2281 ((uint *)lcdbuffer)[y+(x<<1)+10]=
2282 ((uint *)lcdbuffer)[y+(x<<1)+11]=FPAL[(tilepix >> 2)&0x03];
2283 if ((tilepix>>8)&0x03)
2284 ((uint *)lcdbuffer)[y+(x<<1)+12]=
2285 ((uint *)lcdbuffer)[y+(x<<1)+13]=FPAL[(tilepix >> 8)&0x03];
2286 if (tilepix&0x03)
2287 ((uint *)lcdbuffer)[y+(x<<1)+14]=
2288 ((uint *)lcdbuffer)[y+(x<<1)+15]=FPAL[tilepix&0x03];
2289 }
2290 }
2291 }
2292
2293 }
2294 }
2295
gb_scanline32(void)2296 void gb_scanline32(void)
2297 {
2298 register int x,y,tx,ty,xc,tmp;
2299 register uchar *tileofs,*tiledata,*sprofs;
2300 register uchar tile,tile1,tile2;
2301 register uint tilepix;
2302 register ulong *lcdbuf;
2303 register uchar *zbuf;
2304 uchar zbuffer[GB_XBUFFERSIZE];
2305 ulong FPAL[4];
2306
2307 FPAL[0]=GB_STDPAL[BGP & 0x03];
2308 FPAL[1]=GB_STDPAL[(BGP >> 2)& 0x03];
2309 FPAL[2]=GB_STDPAL[(BGP >> 4)& 0x03];
2310 FPAL[3]=GB_STDPAL[BGP >> 6];
2311
2312 y=LY*GB_XBUFFERSIZE;
2313 if (doublesize) y<<=2;
2314
2315 if (LCDC & 0x01) { /* if BG enabled */
2316 tileofs=vram[0]
2317 +((((LY+SCY)&0xFF) >> 3)<<5)+(LCDC & 0x08 ? 0x1C00 : 0x1800);
2318 xc=((LCDC & 0x20)&&(WY<=LY) ? ((WX<7 ? 0 : WX-7) >> 3) : 21);
2319 xc=xc>21 ? 21 : xc;
2320 for (tx=0,x=8-(SCX & 7);tx<xc;tx++,x+=8) {
2321 tile=tileofs[(tx+(SCX>>3))&0x1F];
2322 tiledata=LCDC & 0x10 ? vram[0]+((int)tile<<4)
2323 : vram[0]+0x1000+((int)((signed char)tile)<<4);
2324 tiledata+=((LY+SCY)&7)<<1;
2325 tilepix=((uint)(tiledata[1]&0xAA)<<8)|((uint)(tiledata[0]&0xAA)<<7)|
2326 (tiledata[0]&0x55)|((tiledata[1]&0x55)<<1);
2327
2328 do_tilepix(ulong, 2);
2329 }
2330 } else { /* if BG not enabled */
2331 ulong *p;
2332
2333 memset(zbuffer,0,GB_XBUFFERSIZE);
2334
2335 p=(ulong *)lcdbuffer+y;
2336 if (doublesize)
2337 for (x=0;x<GB_XBUFFERSIZE*2;x++) *p++=FPAL[0];
2338 else
2339 for (x=0;x<GB_XBUFFERSIZE;x++) *p++=FPAL[0];
2340
2341 }
2342
2343 if ((LCDC & 0x20)&&(WY<=LY)&&(WX<167)) { /* if window is on and visible */
2344
2345 y=LY*GB_XBUFFERSIZE;
2346 if (doublesize) y<<=2;
2347
2348 x=WX+1;xc=167-WX;
2349 tileofs=vram[0]+(((LY-WY) >> 3)<<5)+(LCDC & 0x40 ? 0x1C00 : 0x1800);
2350 for (tx=0;xc>0;xc-=8,x+=8,tx++) {
2351 tiledata=LCDC & 0x10 ? vram[0]+((int)tileofs[tx]<<4)
2352 : vram[0]+0x1000+((int)((signed char)tileofs[tx])<<4);
2353 tiledata+=((LY-WY)&7)<<1;
2354 tilepix=((uint)(tiledata[1]&0xAA)<<8)|((uint)(tiledata[0]&0xAA)<<7)|
2355 (tiledata[0]&0x55)|((tiledata[1]&0x55)<<1);
2356
2357 do_tilepix(ulong, 2);
2358 }
2359 }
2360
2361 if (LCDC & 0x02) { /* sprites enabled */
2362 ty=LCDC & 0x04 ? 16 : 8;
2363
2364 y=LY*GB_XBUFFERSIZE;
2365 if (doublesize) y<<=2;
2366
2367 /* sprites */
2368 for (xc=GB_SPRITECOUNT-1,sprofs=oam+0x9C;xc>=0;xc--,sprofs-=4) {
2369 tmp=LY-sprofs[0]+16;
2370 if ((tmp>=0)&&(tmp<ty)&&(sprofs[1]<GB_LCDXSCREENSIZE+8)) {
2371 if (sprofs[3]&0x40) tmp=ty-1-tmp;
2372 tiledata=vram[0]
2373 +(((uint)(sprofs[2] & (LCDC & 0x04 ? 0xFE : 0xFF)))<<4)
2374 +(tmp<<1);
2375 if (sprofs[3]&0x20) {
2376 tile1=H_Flip[tiledata[0]];
2377 tile2=H_Flip[tiledata[1]];
2378 } else {
2379 tile1=tiledata[0];
2380 tile2=tiledata[1];
2381 }
2382 tilepix=((uint)(tile2&0xAA)<<8)|((uint)(tile1&0xAA)<<7)|
2383 (tile1&0x55)|((tile2&0x55)<<1);
2384 x=sprofs[1];
2385
2386 if (sprofs[3]&0x10) {
2387 FPAL[0]=GB_STDPAL[OBP1 & 0x03];
2388 FPAL[1]=GB_STDPAL[(OBP1 >> 2)& 0x03];
2389 FPAL[2]=GB_STDPAL[(OBP1 >> 4)& 0x03];
2390 FPAL[3]=GB_STDPAL[OBP1 >> 6];
2391 } else {
2392 FPAL[0]=GB_STDPAL[OBP0 & 0x03];
2393 FPAL[1]=GB_STDPAL[(OBP0 >> 2)& 0x03];
2394 FPAL[2]=GB_STDPAL[(OBP0 >> 4)& 0x03];
2395 FPAL[3]=GB_STDPAL[OBP0 >> 6];
2396 }
2397
2398 if (sprofs[3]&0x80) {
2399
2400 if (!doublesize) {
2401 lcdbuf=(ulong*)lcdbuffer+x+y;
2402 zbuf=zbuffer+x;
2403 if ((!*zbuf++)&&(tilepix>>14))
2404 *lcdbuf=FPAL[tilepix >> 14];
2405 if ((!*zbuf++)&&((tilepix>>6)&0x03))
2406 *(lcdbuf+1)=FPAL[(tilepix >> 6)&0x03];
2407 if ((!*zbuf++)&&((tilepix>>12)&0x03))
2408 *(lcdbuf+2)=FPAL[(tilepix >> 12)&0x03];
2409 if ((!*zbuf++)&&((tilepix>>4)&0x03))
2410 *(lcdbuf+3)=FPAL[(tilepix >> 4)&0x03];
2411 if ((!*zbuf++)&&((tilepix>>10)&0x03))
2412 *(lcdbuf+4)=FPAL[(tilepix >> 10)&0x03];
2413 if ((!*zbuf++)&&((tilepix>>2)&0x03))
2414 *(lcdbuf+5)=FPAL[(tilepix >> 2)&0x03];
2415 if ((!*zbuf++)&&((tilepix>>8)&0x03))
2416 *(lcdbuf+6)=FPAL[(tilepix >> 8)&0x03];
2417 if ((!*zbuf++)&&(tilepix&0x03))
2418 *(lcdbuf+7)=FPAL[tilepix&0x03];
2419 } else {
2420 if ((zbuffer[x]==0)&&(tilepix>>14))
2421 ((ulong *)lcdbuffer)[y+(x<<1) ]=
2422 ((ulong *)lcdbuffer)[y+(x<<1)+1]=FPAL[tilepix >> 14];
2423 if ((zbuffer[x+1]==0)&&((tilepix>>6)&0x03))
2424 ((ulong *)lcdbuffer)[y+(x<<1)+2]=
2425 ((ulong *)lcdbuffer)[y+(x<<1)+3]=FPAL[(tilepix >> 6)&0x03];
2426 if ((zbuffer[x+2]==0)&&((tilepix>>12)&0x03))
2427 ((ulong *)lcdbuffer)[y+(x<<1)+4]=
2428 ((ulong *)lcdbuffer)[y+(x<<1)+5]=FPAL[(tilepix >> 12)&0x03];
2429 if ((zbuffer[x+3]==0)&&((tilepix>>4)&0x03))
2430 ((ulong *)lcdbuffer)[y+(x<<1)+6]=
2431 ((ulong *)lcdbuffer)[y+(x<<1)+7]=FPAL[(tilepix >> 4)&0x03];
2432 if ((zbuffer[x+4]==0)&&((tilepix>>10)&0x03))
2433 ((ulong *)lcdbuffer)[y+(x<<1)+8]=
2434 ((ulong *)lcdbuffer)[y+(x<<1)+9]=FPAL[(tilepix >> 10)&0x03];
2435 if ((zbuffer[x+5]==0)&&((tilepix>>2)&0x03))
2436 ((ulong *)lcdbuffer)[y+(x<<1)+10]=
2437 ((ulong *)lcdbuffer)[y+(x<<1)+11]=FPAL[(tilepix >> 2)&0x03];
2438 if ((zbuffer[x+6]==0)&&((tilepix>>8)&0x03))
2439 ((ulong *)lcdbuffer)[y+(x<<1)+12]=
2440 ((ulong *)lcdbuffer)[y+(x<<1)+13]=FPAL[(tilepix >> 8)&0x03];
2441 if ((zbuffer[x+7]==0)&&(tilepix&0x03))
2442 ((ulong *)lcdbuffer)[y+(x<<1)+14]=
2443 ((ulong *)lcdbuffer)[y+(x<<1)+15]=FPAL[tilepix&0x03];
2444 }
2445 } else {
2446
2447 if (!doublesize) {
2448 lcdbuf=(ulong*)lcdbuffer+x+y;
2449 if (tilepix>>14)
2450 *lcdbuf=FPAL[tilepix >> 14];
2451 if ((tilepix>>6)&0x03)
2452 *(lcdbuf+1)=FPAL[(tilepix >> 6)&0x03];
2453 if ((tilepix>>12)&0x03)
2454 *(lcdbuf+2)=FPAL[(tilepix >> 12)&0x03];
2455 if ((tilepix>>4)&0x03)
2456 *(lcdbuf+3)=FPAL[(tilepix >> 4)&0x03];
2457 if ((tilepix>>10)&0x03)
2458 *(lcdbuf+4)=FPAL[(tilepix >> 10)&0x03];
2459 if ((tilepix>>2)&0x03)
2460 *(lcdbuf+5)=FPAL[(tilepix >> 2)&0x03];
2461 if ((tilepix>>8)&0x03)
2462 *(lcdbuf+6)=FPAL[(tilepix >> 8)&0x03];
2463 if (tilepix&0x03)
2464 *(lcdbuf+7)=FPAL[tilepix&0x03];
2465 } else {
2466 if (tilepix>>14)
2467 ((ulong *)lcdbuffer)[y+(x<<1) ]=
2468 ((ulong *)lcdbuffer)[y+(x<<1)+1]=FPAL[tilepix >> 14];
2469 if ((tilepix>>6)&0x03)
2470 ((ulong *)lcdbuffer)[y+(x<<1)+2]=
2471 ((ulong *)lcdbuffer)[y+(x<<1)+3]=FPAL[(tilepix >> 6)&0x03];
2472 if ((tilepix>>12)&0x03)
2473 ((ulong *)lcdbuffer)[y+(x<<1)+4]=
2474 ((ulong *)lcdbuffer)[y+(x<<1)+5]=FPAL[(tilepix >> 12)&0x03];
2475 if ((tilepix>>4)&0x03)
2476 ((ulong *)lcdbuffer)[y+(x<<1)+6]=
2477 ((ulong *)lcdbuffer)[y+(x<<1)+7]=FPAL[(tilepix >> 4)&0x03];
2478 if ((tilepix>>10)&0x03)
2479 ((ulong *)lcdbuffer)[y+(x<<1)+8]=
2480 ((ulong *)lcdbuffer)[y+(x<<1)+9]=FPAL[(tilepix >> 10)&0x03];
2481 if ((tilepix>>2)&0x03)
2482 ((ulong *)lcdbuffer)[y+(x<<1)+10]=
2483 ((ulong *)lcdbuffer)[y+(x<<1)+11]=FPAL[(tilepix >> 2)&0x03];
2484 if ((tilepix>>8)&0x03)
2485 ((ulong *)lcdbuffer)[y+(x<<1)+12]=
2486 ((ulong *)lcdbuffer)[y+(x<<1)+13]=FPAL[(tilepix >> 8)&0x03];
2487 if (tilepix&0x03)
2488 ((ulong *)lcdbuffer)[y+(x<<1)+14]=
2489 ((ulong *)lcdbuffer)[y+(x<<1)+15]=FPAL[tilepix&0x03];
2490 }
2491 }
2492 }
2493 }
2494 }
2495 }
2496
cgb_scanline32(void)2497 void cgb_scanline32(void)
2498 {
2499 int x,y,tx,ty,xc,tmp;
2500 uchar *tileofs1,*tileofs2,*tiledata,*sprofs;
2501 uchar tile,tile1,tile2,tile_a;
2502 uint tilepix,tilenum;
2503 uchar zbuffer[GB_XBUFFERSIZE];
2504 ulong FPAL[4];
2505
2506 y=LY*GB_XBUFFERSIZE;
2507 if (doublesize) y<<=2;
2508
2509 if (LCDC & 0x01) { /* if BG enabled */
2510 tilenum=((((LY+SCY)&0xFF) >> 3)<<5)+(LCDC & 0x08 ? 0x1C00 : 0x1800);
2511 tileofs1=vram[0]+tilenum;
2512 tileofs2=vram[1]+tilenum;
2513 xc=((LCDC & 0x20)&&(WY<=LY) ? ((WX<7 ? 0 : WX-7) >> 3) : 21);
2514 xc=xc>21 ? 21 : xc;
2515 for (tx=0,x=8-(SCX & 7);tx<xc;tx++,x+=8) {
2516 tile=tileofs1[(tx+(SCX>>3))&0x1F];
2517 tile_a=tileofs2[(tx+(SCX>>3))&0x1F];
2518 tiledata=LCDC & 0x10 ? vram[(tile_a>>3)&1]+((int)tile<<4)
2519 : vram[(tile_a>>3)&1]+0x1000+((int)((signed char)tile)<<4);
2520 tiledata+=(tile_a&0x40) ? (7-((LY+SCY)&7))<<1:((LY+SCY)&7)<<1;
2521 tile1=tiledata[0];tile2=tiledata[1];
2522 if (tile_a&0x20) {tile1=H_Flip[tile1];tile2=H_Flip[tile2];}
2523
2524 tilepix=((uint)(tile2&0xAA)<<8)|((uint)(tile1&0xAA)<<7)|
2525 (tile1&0x55)|((tile2&0x55)<<1);
2526
2527 FPAL[0]=BGPAL[tile_a&7][0];
2528 FPAL[1]=BGPAL[tile_a&7][1];
2529 FPAL[2]=BGPAL[tile_a&7][2];
2530 FPAL[3]=BGPAL[tile_a&7][3];
2531
2532 do_tilepix(ulong, 2);
2533 }
2534 } else { /* if BG not enabled */
2535 ulong *p;
2536
2537 memset(zbuffer,0,GB_XBUFFERSIZE);
2538
2539 p=(ulong *)lcdbuffer+y;
2540 if (doublesize)
2541 for (x=0;x<GB_XBUFFERSIZE*2;x++) *p++=0; /* 0 or background ? */
2542 else
2543 for (x=0;x<GB_XBUFFERSIZE;x++) *p++=0; /* 0 or background ? */
2544
2545 }
2546
2547 if ((LCDC & 0x20)&&(WY<=LY)&&(WX<167)) { /* if window is on and visible */
2548
2549 y=LY*GB_XBUFFERSIZE;
2550 if (doublesize) y<<=2;
2551
2552 x=WX+1;xc=167-WX;
2553 tilenum=(((LY-WY) >> 3)<<5)+(LCDC & 0x40 ? 0x1C00 : 0x1800);
2554 tileofs1=vram[0]+tilenum;
2555 tileofs2=vram[1]+tilenum;
2556 for (tx=0;xc>0;xc-=8,x+=8,tx++) {
2557 tile_a=tileofs2[tx];
2558 tiledata=LCDC & 0x10 ? vram[(tile_a>>3)&1]+((int)tileofs1[tx]<<4)
2559 : vram[(tile_a>>3)&1]+0x1000+((int)((signed char)tileofs1[tx])<<4);
2560
2561 tiledata+=(tile_a&0x40) ? (7-((LY-WY)&7))<<1:((LY-WY)&7)<<1;
2562 tile1=tiledata[0];tile2=tiledata[1];
2563 if (tile_a&0x20) {tile1=H_Flip[tile1];tile2=H_Flip[tile2];}
2564
2565 tilepix=((uint)(tile2&0xAA)<<8)|((uint)(tile1&0xAA)<<7)|
2566 (tile1&0x55)|((tile2&0x55)<<1);
2567
2568 FPAL[0]=BGPAL[tile_a&7][0];
2569 FPAL[1]=BGPAL[tile_a&7][1];
2570 FPAL[2]=BGPAL[tile_a&7][2];
2571 FPAL[3]=BGPAL[tile_a&7][3];
2572
2573 do_tilepix(ulong, 2);
2574 }
2575 }
2576
2577 if (LCDC & 0x02) { /* sprites enabled */
2578 ty=LCDC & 0x04 ? 16 : 8;
2579
2580 y=LY*GB_XBUFFERSIZE;
2581 if (doublesize) y<<=2;
2582
2583 /* background sprites */
2584 for (xc=GB_SPRITECOUNT-1,sprofs=oam+0x9C;xc>=0;xc--,sprofs-=4) {
2585 tmp=LY-sprofs[0]+16;
2586 if ((sprofs[3]&0x80)&&(tmp>=0)&&(tmp<ty)&&
2587 (sprofs[1]<GB_LCDXSCREENSIZE+8)) {
2588 if (sprofs[3]&0x40) tmp=ty-1-tmp;
2589 tiledata=vram[(sprofs[3]>>3)&1]
2590 +(((uint)(sprofs[2] & (LCDC & 0x04 ? 0xFE : 0xFF)))<<4)
2591 +(tmp<<1);
2592 if (sprofs[3]&0x20) {
2593 tile1=H_Flip[tiledata[0]];
2594 tile2=H_Flip[tiledata[1]];
2595 } else {
2596 tile1=tiledata[0];
2597 tile2=tiledata[1];
2598 }
2599 tilepix=((uint)(tile2&0xAA)<<8)|((uint)(tile1&0xAA)<<7)|
2600 (tile1&0x55)|((tile2&0x55)<<1);
2601 x=sprofs[1];
2602
2603 FPAL[0]=OBJPAL[sprofs[3]&7][0];
2604 FPAL[1]=OBJPAL[sprofs[3]&7][1];
2605 FPAL[2]=OBJPAL[sprofs[3]&7][2];
2606 FPAL[3]=OBJPAL[sprofs[3]&7][3];
2607
2608 if (!doublesize) {
2609 if ((zbuffer[x]==0)&&(tilepix>>14))
2610 ((ulong *)lcdbuffer)[y+x]=FPAL[tilepix >> 14];
2611 if ((zbuffer[x+1]==0)&&((tilepix>>6)&0x03))
2612 ((ulong *)lcdbuffer)[y+x+1]=FPAL[(tilepix >> 6)&0x03];
2613 if ((zbuffer[x+2]==0)&&((tilepix>>12)&0x03))
2614 ((ulong *)lcdbuffer)[y+x+2]=FPAL[(tilepix >> 12)&0x03];
2615 if ((zbuffer[x+3]==0)&&((tilepix>>4)&0x03))
2616 ((ulong *)lcdbuffer)[y+x+3]=FPAL[(tilepix >> 4)&0x03];
2617 if ((zbuffer[x+4]==0)&&((tilepix>>10)&0x03))
2618 ((ulong *)lcdbuffer)[y+x+4]=FPAL[(tilepix >> 10)&0x03];
2619 if ((zbuffer[x+5]==0)&&((tilepix>>2)&0x03))
2620 ((ulong *)lcdbuffer)[y+x+5]=FPAL[(tilepix >> 2)&0x03];
2621 if ((zbuffer[x+6]==0)&&((tilepix>>8)&0x03))
2622 ((ulong *)lcdbuffer)[y+x+6]=FPAL[(tilepix >> 8)&0x03];
2623 if ((zbuffer[x+7]==0)&&(tilepix&0x03))
2624 ((ulong *)lcdbuffer)[y+x+7]=FPAL[tilepix&0x03];
2625 } else {
2626 if ((zbuffer[x]==0)&&(tilepix>>14))
2627 ((ulong *)lcdbuffer)[y+(x<<1) ]=
2628 ((ulong *)lcdbuffer)[y+(x<<1)+1]=FPAL[tilepix >> 14];
2629 if ((zbuffer[x+1]==0)&&((tilepix>>6)&0x03))
2630 ((ulong *)lcdbuffer)[y+(x<<1)+2]=
2631 ((ulong *)lcdbuffer)[y+(x<<1)+3]=FPAL[(tilepix >> 6)&0x03];
2632 if ((zbuffer[x+2]==0)&&((tilepix>>12)&0x03))
2633 ((ulong *)lcdbuffer)[y+(x<<1)+4]=
2634 ((ulong *)lcdbuffer)[y+(x<<1)+5]=FPAL[(tilepix >> 12)&0x03];
2635 if ((zbuffer[x+3]==0)&&((tilepix>>4)&0x03))
2636 ((ulong *)lcdbuffer)[y+(x<<1)+6]=
2637 ((ulong *)lcdbuffer)[y+(x<<1)+7]=FPAL[(tilepix >> 4)&0x03];
2638 if ((zbuffer[x+4]==0)&&((tilepix>>10)&0x03))
2639 ((ulong *)lcdbuffer)[y+(x<<1)+8]=
2640 ((ulong *)lcdbuffer)[y+(x<<1)+9]=FPAL[(tilepix >> 10)&0x03];
2641 if ((zbuffer[x+5]==0)&&((tilepix>>2)&0x03))
2642 ((ulong *)lcdbuffer)[y+(x<<1)+10]=
2643 ((ulong *)lcdbuffer)[y+(x<<1)+11]=FPAL[(tilepix >> 2)&0x03];
2644 if ((zbuffer[x+6]==0)&&((tilepix>>8)&0x03))
2645 ((ulong *)lcdbuffer)[y+(x<<1)+12]=
2646 ((ulong *)lcdbuffer)[y+(x<<1)+13]=FPAL[(tilepix >> 8)&0x03];
2647 if ((zbuffer[x+7]==0)&&(tilepix&0x03))
2648 ((ulong *)lcdbuffer)[y+(x<<1)+14]=
2649 ((ulong *)lcdbuffer)[y+(x<<1)+15]=FPAL[tilepix&0x03];
2650 }
2651 }
2652 }
2653
2654 /* foreground sprites */
2655 for (xc=GB_SPRITECOUNT-1,sprofs=oam+0x9C;xc>=0;xc--,sprofs-=4) {
2656 tmp=LY-sprofs[0]+16;
2657 if (((sprofs[3]&0x80)==0)&&(tmp>=0)&&(tmp<ty)&&
2658 (sprofs[1]<GB_LCDXSCREENSIZE+8)) {
2659 if (sprofs[3]&0x40) tmp=ty-1-tmp;
2660 tiledata=vram[(sprofs[3]>>3)&1]
2661 +(((uint)(sprofs[2] & (LCDC & 0x04 ? 0xFE : 0xFF)))<<4)
2662 +(tmp<<1);
2663 if (sprofs[3]&0x20) {
2664 tile1=H_Flip[tiledata[0]];
2665 tile2=H_Flip[tiledata[1]];
2666 } else {
2667 tile1=tiledata[0];
2668 tile2=tiledata[1];
2669 }
2670 tilepix=((uint)(tile2&0xAA)<<8)|((uint)(tile1&0xAA)<<7)|
2671 (tile1&0x55)|((tile2&0x55)<<1);
2672 x=sprofs[1];
2673
2674 FPAL[0]=OBJPAL[sprofs[3]&7][0];
2675 FPAL[1]=OBJPAL[sprofs[3]&7][1];
2676 FPAL[2]=OBJPAL[sprofs[3]&7][2];
2677 FPAL[3]=OBJPAL[sprofs[3]&7][3];
2678
2679 if (!doublesize) {
2680 if (tilepix>>14)
2681 ((ulong *)lcdbuffer)[y+x]=FPAL[tilepix >> 14];
2682 if ((tilepix>>6)&0x03)
2683 ((ulong *)lcdbuffer)[y+x+1]=FPAL[(tilepix >> 6)&0x03];
2684 if ((tilepix>>12)&0x03)
2685 ((ulong *)lcdbuffer)[y+x+2]=FPAL[(tilepix >> 12)&0x03];
2686 if ((tilepix>>4)&0x03)
2687 ((ulong *)lcdbuffer)[y+x+3]=FPAL[(tilepix >> 4)&0x03];
2688 if ((tilepix>>10)&0x03)
2689 ((ulong *)lcdbuffer)[y+x+4]=FPAL[(tilepix >> 10)&0x03];
2690 if ((tilepix>>2)&0x03)
2691 ((ulong *)lcdbuffer)[y+x+5]=FPAL[(tilepix >> 2)&0x03];
2692 if ((tilepix>>8)&0x03)
2693 ((ulong *)lcdbuffer)[y+x+6]=FPAL[(tilepix >> 8)&0x03];
2694 if (tilepix&0x03)
2695 ((ulong *)lcdbuffer)[y+x+7]=FPAL[tilepix&0x03];
2696 } else {
2697 if (tilepix>>14)
2698 ((ulong *)lcdbuffer)[y+(x<<1) ]=
2699 ((ulong *)lcdbuffer)[y+(x<<1)+1]=FPAL[tilepix >> 14];
2700 if ((tilepix>>6)&0x03)
2701 ((ulong *)lcdbuffer)[y+(x<<1)+2]=
2702 ((ulong *)lcdbuffer)[y+(x<<1)+3]=FPAL[(tilepix >> 6)&0x03];
2703 if ((tilepix>>12)&0x03)
2704 ((ulong *)lcdbuffer)[y+(x<<1)+4]=
2705 ((ulong *)lcdbuffer)[y+(x<<1)+5]=FPAL[(tilepix >> 12)&0x03];
2706 if ((tilepix>>4)&0x03)
2707 ((ulong *)lcdbuffer)[y+(x<<1)+6]=
2708 ((ulong *)lcdbuffer)[y+(x<<1)+7]=FPAL[(tilepix >> 4)&0x03];
2709 if ((tilepix>>10)&0x03)
2710 ((ulong *)lcdbuffer)[y+(x<<1)+8]=
2711 ((ulong *)lcdbuffer)[y+(x<<1)+9]=FPAL[(tilepix >> 10)&0x03];
2712 if ((tilepix>>2)&0x03)
2713 ((ulong *)lcdbuffer)[y+(x<<1)+10]=
2714 ((ulong *)lcdbuffer)[y+(x<<1)+11]=FPAL[(tilepix >> 2)&0x03];
2715 if ((tilepix>>8)&0x03)
2716 ((ulong *)lcdbuffer)[y+(x<<1)+12]=
2717 ((ulong *)lcdbuffer)[y+(x<<1)+13]=FPAL[(tilepix >> 8)&0x03];
2718 if (tilepix&0x03)
2719 ((ulong *)lcdbuffer)[y+(x<<1)+14]=
2720 ((ulong *)lcdbuffer)[y+(x<<1)+15]=FPAL[tilepix&0x03];
2721 }
2722 }
2723 }
2724
2725
2726 }
2727 }
2728
storescanline(void)2729 void storescanline(void)
2730 {
2731 #ifdef HARDDEBUG
2732 fprintf(OUTSTREAM,"Drawing scanline %d (LCDC: %02X).\n",LY,LCDC);
2733 #endif
2734
2735 if ((LCDC & 0x80)==0) {
2736 memset(lcdbuffer+(uint)LY*GB_XBUFFERSIZE*(bitmapbits>>3),
2737 0,GB_XBUFFERSIZE*(bitmapbits>>3));
2738 return;
2739 }
2740
2741 (*scanline)();
2742 }
2743
2744 /* horizontal HDMA processing */
hdma_update(void)2745 void hdma_update(void)
2746 {
2747 int i;
2748
2749 if (hdmastarted) {
2750 #ifdef HARDDEBUG
2751 printf("Horizontal blank transfer.\n");
2752 #endif
2753
2754 for (i=16;i>0;i--,hdmadst++,hdmasrc++)
2755 vram[VBK&1][hdmadst&0x1FFF]=GetByteAt(hdmasrc);
2756 if (((HDMA5&0x7F)==0)||(hdmastarted<0)) {
2757 hdmastarted=0;
2758 HDMA5=0x80;
2759 } else
2760 /* HDMA5=(HDMA5&0x80)|((HDMA5&0x7F)-1);*/
2761 HDMA5--;
2762 }
2763 HDMA1=hdmasrc>>8;
2764 HDMA2=hdmasrc&0xF0;
2765 HDMA3=(hdmadst>>8)&0x1F;
2766 HDMA4=hdmadst&0xF0;
2767 }
2768
gameboyspecifics(void)2769 void gameboyspecifics(void)
2770 {
2771 #ifdef DIALOGLINK
2772 int n;
2773 #endif
2774
2775 /* global ticks */
2776 Z80_CPUCLKS+=Z80_TICKS;
2777
2778 /* divider update */
2779 dividerclks-=Z80_TICKS;
2780 if (dividerclks<0) {
2781 dividerclks+=GB_DIVLOAD;
2782 DIV++;
2783 }
2784
2785 soundclks-=Z80_TICKS;
2786 if (soundclks<0) {
2787 soundclks+=snd_updateclks;
2788 #ifdef SOUND
2789 if (usingsound) processSound();
2790 #endif
2791 }
2792
2793 #ifdef DIALOGLINK
2794 serialioclks-=Z80_TICKS;
2795 if (serialioclks<0) {
2796 if (colormode)
2797 serialioclks=serialclks[(SC&2)>>1][DBLSPEED];
2798 else serialioclks=serialclks[0][0];
2799
2800 if ((n=dlglink_getbyte())>=0) {
2801 if ((SC&0x01)==0) dlglink_sndbyte(siosendout);
2802 SB=n;
2803 #ifdef HARDDEBUG
2804 printf("Got: %02X\n",SB);
2805 #endif
2806 SC&=0x7F;
2807 IF|=0x08;
2808 }
2809
2810 }
2811 #endif
2812
2813 /* ******************** */
2814 #ifndef SOUND
2815 soundcounter-=Z80_TICKS;
2816 if (soundcounter<0) NR52&=0xF7;
2817 #endif
2818 /* ******************** */
2819
2820 /* video update */
2821
2822 lcdclks-=Z80_TICKS;
2823 if (LCDC & 0x80) { /* if lcd on */
2824 if (lcdclks<0) {
2825 lcdphase++;
2826 if (lcdphase==3) {
2827 if ((LY>142)&&(LY<153)) {
2828 lcdclks=GB_VCLKS[3];lcdphase--;
2829 hdma_update();
2830 if ((STAT&3)!=1) { /* v-blank */
2831 STAT=(STAT&0xFC)|1;vblankoccured=1;
2832 vblankdelay=GB_VBLANKDELAYCLKS;
2833 } else {
2834 if (LY==148) drawscreen();
2835 }
2836 } else {
2837 lcdphase=0;STAT=(STAT&0xFC)|2;
2838 lcdclks=GB_VCLKS[0];
2839 if ((IE&2)&&(STAT&0x20)) IF|=2; /* lcd oam */
2840 hdma_update();
2841 }
2842 LY=LY==153 ? 0 : LY+1;
2843
2844 STAT&=0xFB;
2845 STAT|=(((LYC==0)&&(LY==153))||(LY==LYC)) ? 0x04 : 0;
2846
2847 if (/*(IE&2)&&*/(STAT&0x40))
2848 if (((LYC!=0)&&(LY==LYC))||((LYC==0)&&(LY==153))) IF|=2;
2849 /* lcd y coincidence */
2850 /* & double null coincidence */
2851 } else {
2852 if (LY<144) {
2853 lcdclks=GB_VCLKS[lcdphase];
2854 if (lcdphase==1) STAT=(STAT&0xFC)|3;
2855 else {
2856 STAT&=0xFC;
2857 storescanline();
2858 if ((IE&2)&&(STAT&0x08)) IF|=2; /* lcd h-blank */
2859 }
2860 }
2861 }
2862 }
2863 } else {
2864 if (lcdclks<0) {
2865 lcdphase=lcdphase==2 ? 0 : lcdphase+1;
2866 lcdclks=GB_VCLKS[lcdphase];
2867 STAT&=0xFC;
2868 switch (lcdphase) {
2869 case 0:STAT|=2;break;
2870 case 1:STAT|=3;storescanline();break;
2871 }
2872 }
2873 }
2874
2875 /* v-blank interrupt handler */
2876 if (vblankdelay<0) {
2877 if ((vblankoccured)||(IF&1)) {
2878 IF|=STAT & 0x10 ? 3 : 1;vblankoccured=0;
2879 if ((Z80_IE)&&(IE&1)) {
2880 Z80_IE=0;Z80_HALTED=0;IF&=0xFE;
2881 #if 0
2882 for (soundclks=0x10;soundclks<0x27;soundclks++)
2883 printf("%02X,",io[soundclks]);
2884 printf("\n");
2885 #endif
2886
2887
2888 #ifdef HARDDEBUG
2889 fprintf(OUTSTREAM,"V-blank interrupt.\n");
2890 #endif
2891 M_RST(0x40);/* lcdclks-=16;*/
2892 }
2893 }
2894 } else vblankdelay-=Z80_TICKS;
2895
2896 if ((Z80_IE)&&(IF&2)&&(IE&2)) {
2897 Z80_IE=0;Z80_HALTED=0;IF&=0xFD;
2898 #ifdef HARDDEBUG
2899 fprintf(OUTSTREAM,"LCDSTAT interrupt.\n");
2900 #endif
2901 M_RST(0x48);/* lcdclks-=24;*/
2902 }
2903
2904 /* timer interrupt handler */
2905 if (TAC&0x04) {
2906 timerclks-=Z80_TICKS;
2907 if (timerclks<0) {
2908 timerclks+=timerfreq;
2909 TIMA++;
2910 if (TIMA==0) {
2911 TIMA=TMA;IF|=0x04;
2912 }
2913 }
2914 }
2915 if (Z80_IE && (IE&4) && (IF&4)) {
2916 Z80_IE=0;IF&=0xFB;Z80_HALTED=0;
2917 #ifdef HARDDEBUG
2918 fprintf(OUTSTREAM,"Timer interrupt.\n");
2919 #endif
2920 M_RST(0x50);
2921 }
2922
2923 /* serial interrupt handler */
2924 if (IF&0x08) {
2925 #ifndef DIALOGLINK
2926 SC&=0x7F;SB=0xFF;
2927 #endif
2928 if (Z80_IE && (IE&0x08)) {
2929 IF&=0xF7;
2930 Z80_IE=0;Z80_HALTED=0;
2931 #ifdef HARDDEBUG
2932 fprintf(OUTSTREAM,"Serial interrupt.\n");
2933 #endif
2934 M_RST(0x58);
2935 }
2936 }
2937
2938
2939 /* joypad interrupt handler (lowest priority) */
2940
2941 joypadclks-=Z80_TICKS;
2942 if (joypadclks<0) {
2943 joypadclks=GB_JOYCLKS;
2944 joypad();
2945 if (joypadstate!=newjoypadstate || IF&0x10) {
2946 IF|=0x10;joypadstate=newjoypadstate;
2947 if ((IE&0x10)&&(Z80_IE)) {
2948 Z80_IE=0;Z80_HALTED=0;
2949 IF&=0xEF;
2950 #ifdef HARDDEBUG
2951 fprintf(OUTSTREAM,"Joypad interrupt.\n");
2952 #endif
2953 M_RST(0x60);
2954 }
2955 }
2956 }
2957 }
2958
2959