18 * hw_interrupt changes the virtual interrupt lines included in the
19 * specified mask to the values the corresponding bits in i take, and
20 * in doing so, raises the appropriate bit of R_IF for any interrupt
21 * lines that transition from low to high.
24 void hw_interrupt(byte i
, byte mask
)
28 R_IF
|= i
& (hw
.ilines
^ i
);
30 /* FIXME - is this correct? not sure the docs understand... */
31 if ((R_IF
& (R_IF
^ oldif
) & R_IE
) && cpu
.ime
) cpu
.halt
= 0;
32 /* if ((i & (hw.ilines ^ i) & R_IE) && cpu.ime) cpu.halt = 0; */
33 /* if ((i & R_IE) && cpu.ime) cpu.halt = 0; */
41 * hw_dma performs plain old memory-to-oam dma, the original dmg
42 * dma. Although on the hardware it takes a good deal of time, the cpu
43 * continues running during this mode of dma, so no special tricks to
44 * stall the cpu are necessary.
53 for (i
= 0; i
< 160; i
++, a
++)
54 lcd
.oam
.mem
[i
] = readb(a
);
59 void hw_hdma_cmd(byte c
)
65 /* Begin or cancel HDMA */
66 if ((hw
.hdma
|c
) & 0x80)
74 sa
= ((addr
)R_HDMA1
<< 8) | (R_HDMA2
&0xf0);
75 da
= 0x8000 | ((int)(R_HDMA3
&0x1f) << 8) | (R_HDMA4
&0xf0);
77 /* FIXME - this should use cpu time! */
78 /*cpu_timers(102 * cnt);*/
81 writeb(da
++, readb(sa
++));
84 R_HDMA3
= 0x1F & (da
>> 8);
96 sa
= ((addr
)R_HDMA1
<< 8) | (R_HDMA2
&0xf0);
97 da
= 0x8000 | ((int)(R_HDMA3
&0x1f) << 8) | (R_HDMA4
&0xf0);
100 writeb(da
++, readb(sa
++));
103 R_HDMA3
= 0x1F & (da
>> 8);
111 * pad_refresh updates the P1 register from the pad states, generating
112 * the appropriate interrupts (by quickly raising and lowering the
113 * interrupt line) if a transition has been made.
123 R_P1
|= (hw
.pad
& 0x0F);
125 R_P1
|= (hw
.pad
>> 4);
127 if (oldp1
& ~R_P1
& 0x0F)
129 hw_interrupt(IF_PAD
, IF_PAD
);
130 hw_interrupt(0, IF_PAD
);
136 * These simple functions just update the state of a button on the
140 void pad_press(byte k
)
148 void pad_release(byte k
)
156 void pad_set(byte k
, int st
)
158 st
? pad_press(k
) : pad_release(k
);
163 hw
.ilines
= hw
.pad
= 0;
165 memset(ram
.hi
, 0, sizeof ram
.hi
);