bleh, tmp commit...
[ppcskel.git] / main.c
1 /*
2         BootMii - a Free Software replacement for the Nintendo/BroadOn bootloader.
3         Requires mini.
4
5 Copyright (C) 2008, 2009        Haxx Enterprises <bushing@gmail.com>
6 Copyright (C) 2009              Andre Heider "dhewg" <dhewg@wiibrew.org>
7 Copyright (C) 2008, 2009        Hector Martin "marcan" <marcan@marcansoft.com>
8 Copyright (C) 2008, 2009        Sven Peter <svenpeter@gmail.com>
9 Copyright (C) 2009              John Kelley <wiidev@kelley.ca>
10
11 # This code is licensed to you under the terms of the GNU GPL, version 2;
12 # see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
13 */
14
15 #include "bootmii_ppc.h"
16 #include "string.h"
17 #include "ipc.h"
18 #include "mini_ipc.h"
19 #include "nandfs.h"
20 #include "fat.h"
21 #include "malloc.h"
22 #include "diskio.h"
23 #include "printf.h"
24 #include "video_low.h"
25 #include "input.h"
26 #include "console.h"
27 #include "irq.h"
28 #include "usb/core/core.h"
29 #include "usb/drivers/class/hid.h"
30 #include "usb/drivers/bt.h"
31 #include "sha1.h"
32 #include "hollywood.h"
33
34 #define MINIMUM_MINI_VERSION 0x00010001
35
36 otp_t otp;
37 seeprom_t seeprom;
38
39 static void dsp_reset(void)
40 {
41         write16(0x0c00500a, read16(0x0c00500a) & ~0x01f8);
42         write16(0x0c00500a, read16(0x0c00500a) | 0x0010);
43         write16(0x0c005036, 0);
44 }
45
46 static char ascii(char s) {
47   if(s < 0x20) return '.';
48   if(s > 0x7E) return '.';
49   return s;
50 }
51
52 void hexdump(void *d, int len) {
53   u8 *data;
54   int i, off;
55   data = (u8*)d;
56   for (off=0; off<len; off += 16) {
57     printf("%08x  ",off);
58     for(i=0; i<16; i++)
59       if((i+off)>=len) printf("   ");
60       else printf("%02x ",data[off+i]);
61
62     printf(" ");
63     for(i=0; i<16; i++)
64       if((i+off)>=len) printf(" ");
65       else printf("%c",ascii(data[off+i]));
66     printf("\n");
67   }
68 }
69         
70 void testOTP(void)
71 {
72         printf("reading OTP...\n");
73         getotp(&otp);
74         printf("read OTP!\n");
75         printf("OTP:\n");
76         hexdump(&otp, sizeof(otp));
77
78         printf("reading SEEPROM...\n");
79         getseeprom(&seeprom);
80         printf("read SEEPROM!\n");
81         printf("SEEPROM:\n");
82         hexdump(&seeprom, sizeof(seeprom));
83 }
84
85 int main(void)
86 {
87         int vmode = -1;
88         exception_init();
89         dsp_reset();
90
91         irq_initialize();
92         irq_bw_enable(BW_PI_IRQ_RESET);
93         irq_bw_enable(BW_PI_IRQ_HW); //hollywood pic
94         /* external ohci */
95         irq_hw_enable(IRQ_OHCI0);
96         /* internal ohci */
97         irq_hw_enable(IRQ_OHCI1);
98
99         ipc_initialize();
100         ipc_slowping();
101
102         gecko_init();
103     input_init();
104         init_fb(vmode);
105
106         VIDEO_Init(vmode);
107         VIDEO_SetFrameBuffer(get_xfb());
108         VISetupEncoder();
109
110         u32 version = ipc_getvers();
111         u16 mini_version_major = version >> 16 & 0xFFFF;
112         u16 mini_version_minor = version & 0xFFFF;
113         printf("Mini version: %d.%0d\n", mini_version_major, mini_version_minor);
114
115         if (version < MINIMUM_MINI_VERSION) {
116                 printf("Sorry, this version of MINI (armboot.bin)\n"
117                         "is too old, please update to at least %d.%0d.\n", 
118                         (MINIMUM_MINI_VERSION >> 16), (MINIMUM_MINI_VERSION & 0xFFFF));
119                 for (;;) 
120                         ; // better ideas welcome!
121         }
122
123         /* external ohci */
124         usb_init(OHCI0_REG_BASE);
125
126         /* internal ohci */
127         usb_init(OHCI1_REG_BASE);
128
129         /* load HID keyboard driver */
130         usb_hidkb_init();
131
132         /* load BT-USB driver */
133         usb_bt_init();
134
135 wait_kb:
136         /* wait for usb keyboard plugged in */
137         if(!usb_hidkb_inuse()) {
138                 print_str("plug in an usb keyboard", 23);
139         }
140         while(!usb_hidkb_inuse());
141
142         print_str("hello keyboard :)", 17);
143
144 #define FONT_WIDTH  13
145 #define FONT_HEIGHT 15
146 #define STDOUT_BORDER_LEFT 20
147 #define STDOUT_BORDER_RIGHT 650
148 #define STDOUT_BORDER_TOP 20
149 #define STDOUT_BORDER_BOTTOM 550
150 #define TABSIZE 4
151         /* you are welcome to make this nice :) */
152         char str[7];
153         u16 i, j, ret=0, y=STDOUT_BORDER_TOP, x=STDOUT_BORDER_LEFT;
154         u16 old_x, old_y;
155         struct kbrep *k, *old=NULL;
156
157         while(usb_hidkb_inuse()) {
158                 memset(str, '\0', 7);
159                 k = usb_hidkb_getChars();
160                 j=0;
161                 old_x = x; /* save actual x and y position for printing after the loop */
162                 old_y = y;
163                 for(i=0; k->keys[i]>0; i++) {
164
165                         /* dropping char's if necessary */
166                         if(old) {
167                                 for(j=0; j < 6; j++) {
168                                         if(old->keys[j] == k->keys[i]) {
169                                                 ret = 1;
170                                                 break;
171                                         }
172                                 }
173                         }
174                         if(ret) {
175                                 ret = 0;
176                                 continue;
177                         }
178                         j = 0;
179
180                         unsigned char key = usb_hidkb_get_char_from_keycode(k->keys[i],
181                                         (k->mod & MOD_lshift) || (k->mod & MOD_rshift));
182                         /* no key or key not relevant? next, please. */
183                         if (key == 0)
184                                 continue;
185
186                         /* RETURN pressed? */
187                         if (key == '\n') {
188                                 x = STDOUT_BORDER_LEFT;
189                                 y += FONT_HEIGHT;
190                                 printf("\n");
191                         /* TAB pressed? */
192                         } else if (key == '\t') {
193                                 x += (TABSIZE*FONT_WIDTH);
194                                 printf("\t");
195
196                         /* BACKSPACE pressed? */
197                         } else if (key == '\r') {
198                                 /* TODO */
199
200                         /* now we have only printable characters left */
201                         } else {
202                                 x += FONT_WIDTH;
203                                 str[j] = key;
204                                 j++;
205                         }
206
207                         /* line full? break! */
208                         if(x > (STDOUT_BORDER_RIGHT-FONT_WIDTH)) {
209                                 x = STDOUT_BORDER_LEFT;
210                                 y += FONT_HEIGHT;
211                         }
212                         /* screen full? start again at top */
213                         if(y > (STDOUT_BORDER_BOTTOM-FONT_HEIGHT)) {
214                                 y = STDOUT_BORDER_TOP;
215                         }
216                 }
217                 if(old) {
218                         free(old);
219                 }
220                 old = k;
221                 if(j > 0) { /* when there was any printable stuff, show it */
222                         print_str_noscroll(old_x, old_y, str);
223                         printf("%s", str);
224                 }
225         }
226
227         goto wait_kb;
228
229 #if 0
230         printf("===============================\n");
231
232         SHA1TestCases();
233
234         printf("bye, world!\n");
235 #endif
236
237         return 0;
238 }
239