4 #include "rockmacros.h"
14 struct hw hw IBSS_ATTR
;
19 * hw_interrupt changes the virtual interrupt lines included in the
20 * specified mask to the values the corresponding bits in i take, and
21 * in doing so, raises the appropriate bit of R_IF for any interrupt
22 * lines that transition from low to high.
25 void hw_interrupt(byte i
, byte mask
)
29 R_IF
|= i
& (hw
.ilines
^ i
);
31 /* FIXME - is this correct? not sure the docs understand... */
32 if ((R_IF
& (R_IF
^ oldif
) & R_IE
) && cpu
.ime
) cpu
.halt
= 0;
33 /* if ((i & (hw.ilines ^ i) & R_IE) && cpu.ime) cpu.halt = 0; */
34 /* if ((i & R_IE) && cpu.ime) cpu.halt = 0; */
42 * hw_dma performs plain old memory-to-oam dma, the original dmg
43 * dma. Although on the hardware it takes a good deal of time, the cpu
44 * continues running during this mode of dma, so no special tricks to
45 * stall the cpu are necessary.
54 for (i
= 0; i
< 160; i
++, a
++)
55 lcd
.oam
.mem
[i
] = readb(a
);
64 sa
= ((addr
)R_HDMA1
<< 8) | (R_HDMA2
&0xf0);
65 da
= 0x8000 | ((int)(R_HDMA3
&0x1f) << 8) | (R_HDMA4
&0xf0);
66 for (cnt
=16; cnt
>0; cnt
--)
67 writeb(da
++, readb(sa
++));
71 R_HDMA3
= 0x1F & (da
>> 8);
77 void hw_hdma_cmd(byte c
)
83 /* Begin or cancel HDMA */
84 if ((hw
.hdma
|c
) & 0x80)
88 if ((R_STAT
&0x03) == 0x00) hw_hdma();
93 sa
= ((addr
)R_HDMA1
<< 8) | (R_HDMA2
&0xf0);
94 da
= 0x8000 | ((int)(R_HDMA3
&0x1f) << 8) | (R_HDMA4
&0xf0);
95 cnt
= (((int)c
)+1) << 4;
96 /* FIXME - this should use cpu time! */
97 /*cpu_timers(102 * cnt);*/
98 cpu_timers((460>>cpu
.speed
)+cnt
); /*dalias*/
99 /*cpu_timers(228 + (16*cnt));*/ /* this should be right according to no$ */
101 writeb(da
++, readb(sa
++));
104 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.
116 void pad_refresh(void)
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 static void pad_press(byte k
) ICODE_ATTR
;
141 static void pad_press(byte k
)
149 static void pad_release(byte k
) ICODE_ATTR
;
150 static void pad_release(byte k
)
158 void pad_set(byte k
, int st
)
160 st
? pad_press(k
) : pad_release(k
);
165 hw
.ilines
= hw
.pad
= 0;
167 memset(ram
.hi
, 0, sizeof ram
.hi
);