/* lcdc_trans() Main LCDC emulation routine */ void lcdc_trans() { if (R_LCDC & 0x80) { /* LCDC operation enabled */ while (C <= 0) { /* Update current state */ switch ((byte)(R_STAT & 3)) { case 0: /* after hblank */ /* FIXME: first line of first frame will be skipped each time LCDC is started */ if (++R_LY <= 143) { stat_change(2); /* -> search */ } else { stat_change(1); /* -> vblank */ /* See "NOTE A" above */ /*if (cpu.halt) { hw_interrupt(IF_VBLANK, IF_VBLANK); C += 228; } else { C += 10; continue; }*/ break; } break; case 2: /* after search */ stat_change(3); /* -> transfer */ break; case 3: /* after transfer */ stat_change(0); /* -> hblank */ break; case 1: /* after (in) vblank */ if (R_LY == 0) { stat_change(2); /* -> search */ } break; } /* Handle current state */ switch ((byte)(R_STAT & 3)) { case 2: /* search */ if (R_LY == 0) { lcd_begin(); } C += 40; break; case 3: /* transfer */ lcd_refreshline(); C += 86; break; case 0: /* hblank */ if (hw.hdma & 0x80) { hw_hdma(); } C += 102; break; case 1: /* vblank */ if (!(hw.ilines & IF_VBLANK)) { C += 228; /*C += 218; See "NOTE A" above */ hw_interrupt(IF_VBLANK, IF_VBLANK); } else { R_LY++; if (R_LY < 153) { C += 228; } else if (R_LY == 153) { /* Handling special case on the last line part 1; see docs/HACKING */ C += 28; } else { /* Handling special case on the last line part 2; see docs/HACKING */ R_LY = 0; C += 200; } stat_trigger(); } break; } /* switch(state) */ } /* while (C <= 0) */ } /* if (R_LCDC & 0x80) */ else { /* LCDC operation disabled (short route) */ if (C <= 0) /* Original code does in fact return after each pass, there is no loop here */ { switch ((byte)(R_STAT & 3)) { case 2: /* after search */ stat_change(3); C += 86; break; case 3: /* after transfer */ stat_change(0); C += 102; break; case 0: /* after hblank */ stat_change(2); R_LY++; C += 40; break; case 1: /* after (in) vblank */ stat_change(2); C += 40; break; } } } }
void lcdc_trans() { if (!(R_LCDC & 0x80)) { while (C <= 0) { switch ((byte)(R_STAT & 3)) { case 0: case 1: stat_change(2); C += 40; break; case 2: stat_change(3); C += 86; break; case 3: stat_change(0); if (hw.hdma & 0x80) hw_hdma(); else C += 102; break; } return; } } while (C <= 0) { switch ((byte)(R_STAT & 3)) { case 1: if (!(hw.ilines & IF_VBLANK)) { C += 218; hw_interrupt(IF_VBLANK, IF_VBLANK); break; } if (R_LY == 0) { lcd_begin(); stat_change(2); C += 40; break; } else if (R_LY < 152) C += 228; else if (R_LY == 152) C += 28; else { R_LY = -1; C += 200; } R_LY++; stat_trigger(); break; case 2: lcd_refreshline(); stat_change(3); C += 86; break; case 3: stat_change(0); if (hw.hdma & 0x80) hw_hdma(); /* FIXME -- how much of the hblank does hdma use?? */ /* else */ C += 102; break; case 0: if (++R_LY >= 144) { if (cpu.halt) { hw_interrupt(IF_VBLANK, IF_VBLANK); C += 228; } else C += 10; stat_change(1); break; } stat_change(2); C += 40; break; } } }