fix FS#8187 - charging breaks sleep timer. Now if the timer goes off and the player...
[Rockbox.git] / apps / plugins / rockboy / lcdc.c
blob2a1b094929901ec1512b825f9ff2fc2ae01f80a5
1 #include "rockmacros.h"
3 #include "defs.h"
4 #include "hw.h"
5 #include "cpu-gb.h"
6 #include "regs.h"
7 #include "lcd-gb.h"
8 #include "fb.h"
11 #define C (cpu.lcdc)
15 * stat_trigger updates the STAT interrupt line to reflect whether any
16 * of the conditions set to be tested (by bits 3-6 of R_STAT) are met.
17 * This function should be called whenever any of the following occur:
18 * 1) LY or LYC changes.
19 * 2) A state transition affects the low 2 bits of R_STAT (see below).
20 * 3) The program writes to the upper bits of R_STAT.
21 * stat_trigger also updates bit 2 of R_STAT to reflect whether LY=LYC.
24 void stat_trigger(void)
26 static const int condbits[4] = { 0x08, 0x10, 0x20, 0x00 };
27 int flag = 0;
29 if (R_LY == R_LYC)
31 R_STAT |= 0x04;
32 if (R_STAT & 0x40) flag = IF_STAT;
34 else R_STAT &= ~0x04;
36 if (R_STAT & condbits[R_STAT&3]) flag = IF_STAT;
38 if (!(R_LCDC & 0x80)) flag = 0;
40 hw_interrupt(flag, IF_STAT);
44 * stat_change is called when a transition results in a change to the
45 * LCD STAT condition (the low 2 bits of R_STAT). It raises or lowers
46 * the VBLANK interrupt line appropriately and calls stat_trigger to
47 * update the STAT interrupt line.
50 static void stat_change(unsigned int stat)
52 R_STAT = (R_STAT & 0x7C) | stat;
54 if (stat != 1) hw_interrupt(0, IF_VBLANK);
55 /* hw_interrupt((stat == 1) ? IF_VBLANK : 0, IF_VBLANK); */
56 stat_trigger();
60 void lcdc_change(byte b)
62 byte old = R_LCDC;
63 R_LCDC = b;
64 if ((R_LCDC ^ old) & 0x80) /* lcd on/off change */
66 R_LY = 0;
67 stat_change(2);
68 C = 40;
69 lcd_begin();
74 void lcdc_trans(void)
76 if (!(R_LCDC & 0x80))
78 while (C <= 0)
80 switch ((byte)(R_STAT & 3))
82 case 0:
83 case 1:
84 stat_change(2);
85 C += 40;
86 break;
87 case 2:
88 stat_change(3);
89 C += 86;
90 break;
91 case 3:
92 stat_change(0);
93 if (hw.hdma & 0x80)
94 hw_hdma();
95 else
96 C += 102;
97 break;
99 return;
102 while (C <= 0)
104 switch ((byte)(R_STAT & 3))
106 case 1:
107 if (!(hw.ilines & IF_VBLANK))
109 C += 218;
110 hw_interrupt(IF_VBLANK, IF_VBLANK);
111 break;
113 if (R_LY == 0)
115 lcd_begin();
116 stat_change(2);
117 C += 40;
118 break;
120 else if (R_LY < 152)
121 C += 228;
122 else if (R_LY == 152)
123 C += 28;
124 else
126 R_LY = -1;
127 C += 200;
129 R_LY++;
130 stat_trigger();
131 break;
132 case 2:
133 if (fb.enabled)
134 lcd_refreshline();
135 stat_change(3);
136 C += 86;
137 break;
138 case 3:
139 stat_change(0);
140 if (hw.hdma & 0x80)
141 hw_hdma();
142 /* FIXME -- how much of the hblank does hdma use?? */
143 /* else */
144 C += 102;
145 break;
146 case 0:
147 if (++R_LY >= 144)
149 if (cpu.halt)
151 hw_interrupt(IF_VBLANK, IF_VBLANK);
152 C += 228;
154 else C += 10;
155 stat_change(1);
156 break;
158 stat_change(2);
159 C += 40;
160 break;