2 BootMii - a Free Software replacement for the Nintendo/BroadOn bootloader.
5 Input-handling functions for BootMii. Inspired by GC_PAD.c from GCLIB.
7 Copyright (C) 2008, 2009 Haxx Enterprises <bushing@gmail.com>
8 Copyright (C) 2009 Andre Heider "dhewg" <dhewg@wiibrew.org>
9 Copyright (C) 2009 John Kelley <wiidev@kelley.ca>
10 Copyright (C) 2009 bLAStY <blasty@bootmii.org>
12 # This code is licensed to you under the terms of the GNU GPL, version 2;
13 # see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
16 #include "bootmii_ppc.h"
20 #define PADREG(x) (0xCD006400 + (x)*4)
24 static void gcpad_init(void) {
25 write32(PADREG(0), 0x00400300); // read pad on channel 1
26 write32(PADREG(3), 0x00400300);
27 write32(PADREG(6), 0x00400300);
28 write32(PADREG(8), 0x00400300);
29 write32(PADREG(12), 0x000701f0); // enable poll chan 1, X = 7, Y = 1
30 write32(PADREG(14), 0x80000000); // transfer all buffer
33 static void gpio_init(void) {
34 // setup power and eject button hollywood IRQ for PPC
35 mask32(0x0d8000fc, 0, 0x41); // set GPIO owner to PPC
36 mask32(0x0d80003c, 1<<10, 0);
37 mask32(0x0d800034, 0, 1<<10);
38 mask32(0x0d8000d4, 0, 0x41);
39 mask32(0x0d8000cc, 0, 0x41);
42 void input_init(void) {
43 memset(&_pad, 0, sizeof(GC_Pad));
48 // Check for any pending GPIO irq's, which should be ACK'd so we don't get ghost presses later.
49 // Try over and over again, until we are out of them.
50 while (read32(0x0d800030) & (1<<10)) {
51 if (read32(0x0d8000f0) & 1) {
52 while(read32(0x0d8000c8) & 1);
53 write32(0x0d8000d0, 1);
54 } else if (read32(0x0d8000f0) & 0x40) {
55 write32(0x0d8000d0, 0x40);
58 write32(0x0d800030, 1<<10);
61 // No IRQ's left to be ACK'd, continue our business.
64 u16 pad_read(GC_Pad *pad, int chan) {
65 u32 pdata = read32(PADREG(3 * chan + 1));
66 u32 pdata2 = read32(PADREG(3 * chan + 2));
68 u16 btns = pdata >> 16;
71 u16 prev = pad->btns_held;
73 pad->btns_held = btns;
74 pad->btns_up = prev & ~btns;
75 pad->btns_down = btns & (btns ^ prev);
77 pad->x = 128 + ((pdata >> 8) & 0xff);
78 pad->y = 128 - (pdata & 0xff);
80 pad->cx = 128 + (pdata2 >> 24);
81 pad->cy = 128 - ((pdata2 >> 16) & 0xff);
82 pad->l = (pdata2 >> 8) & 0xff;
83 pad->r = pdata2 & 0xff;
85 return pad->btns_down;
91 // TODO: Hackity hack, prevent ghost presses
92 static u8 reset_delay = 5;
99 if (!((read32(0x0C003000) >> 16) & 1) && reset_delay == 0) {
107 if (read32(0x0d800030) & (1<<10)) {
108 irq_flag = read32(0x0d8000f0);
113 while(read32(0x0d8000c8) & 1);
114 write32(0x0d8000d0, 1);
115 } else if (irq_flag & 0x40) {
118 while(read32(0x0d8000c8) & 0x40);
119 write32(0x0d8000d0, 0x40);
122 write32(0x0d800030, 1<<10); // ack GPIO irq
128 u16 input_read(void) {
129 return pad_read(&_pad, 0) | gpio_read();
132 u16 input_wait(void) {
138 } while (!(res & PAD_ANY));