added simple keycode->char lookup functionality
[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 "sha1.h"
31 #include "hollywood.h"
32
33 #define MINIMUM_MINI_VERSION 0x00010001
34
35 otp_t otp;
36 seeprom_t seeprom;
37
38 static void dsp_reset(void)
39 {
40         write16(0x0c00500a, read16(0x0c00500a) & ~0x01f8);
41         write16(0x0c00500a, read16(0x0c00500a) | 0x0010);
42         write16(0x0c005036, 0);
43 }
44
45 static char ascii(char s) {
46   if(s < 0x20) return '.';
47   if(s > 0x7E) return '.';
48   return s;
49 }
50
51 void hexdump(void *d, int len) {
52   u8 *data;
53   int i, off;
54   data = (u8*)d;
55   for (off=0; off<len; off += 16) {
56     printf("%08x  ",off);
57     for(i=0; i<16; i++)
58       if((i+off)>=len) printf("   ");
59       else printf("%02x ",data[off+i]);
60
61     printf(" ");
62     for(i=0; i<16; i++)
63       if((i+off)>=len) printf(" ");
64       else printf("%c",ascii(data[off+i]));
65     printf("\n");
66   }
67 }
68         
69 void testOTP(void)
70 {
71         printf("reading OTP...\n");
72         getotp(&otp);
73         printf("read OTP!\n");
74         printf("OTP:\n");
75         hexdump(&otp, sizeof(otp));
76
77         printf("reading SEEPROM...\n");
78         getseeprom(&seeprom);
79         printf("read SEEPROM!\n");
80         printf("SEEPROM:\n");
81         hexdump(&seeprom, sizeof(seeprom));
82 }
83
84 int main(void)
85 {
86         int vmode = -1;
87         exception_init();
88         dsp_reset();
89
90         irq_initialize();
91         irq_bw_enable(BW_PI_IRQ_RESET);
92         irq_bw_enable(BW_PI_IRQ_HW); //hollywood pic
93         /* external ohci */
94         irq_hw_enable(IRQ_OHCI0);
95         /* internal ohci */
96         //irq_hw_enable(IRQ_OHCI1);
97
98         ipc_initialize();
99         ipc_slowping();
100
101         gecko_init();
102     input_init();
103         init_fb(vmode);
104
105         VIDEO_Init(vmode);
106         VIDEO_SetFrameBuffer(get_xfb());
107         VISetupEncoder();
108
109         u32 version = ipc_getvers();
110         u16 mini_version_major = version >> 16 & 0xFFFF;
111         u16 mini_version_minor = version & 0xFFFF;
112         printf("Mini version: %d.%0d\n", mini_version_major, mini_version_minor);
113
114         if (version < MINIMUM_MINI_VERSION) {
115                 printf("Sorry, this version of MINI (armboot.bin)\n"
116                         "is too old, please update to at least %d.%0d.\n", 
117                         (MINIMUM_MINI_VERSION >> 16), (MINIMUM_MINI_VERSION & 0xFFFF));
118                 for (;;) 
119                         ; // better ideas welcome!
120         }
121
122         /* external ohci */
123         usb_init(OHCI0_REG_BASE);
124
125         /* internal ohci */
126         usb_init(OHCI1_REG_BASE);
127
128         /* load HID keyboard driver */
129         usb_hidkb_init();
130
131         /* wait for usb keyboard plugged in */
132         if(!usb_hidkb_inuse()) {
133                 print_str("plug in an usb keyboard", 23);
134         }
135         while(!usb_hidkb_inuse());
136
137 #define FONT_WIDTH  13
138 #define FONT_HEIGHT 15
139 #define STDOUT_BORDER_LEFT 20
140 #define STDOUT_BORDER_RIGHT 650
141 #define STDOUT_BORDER_TOP 20
142 #define STDOUT_BORDER_BOTTOM 550
143 #define TABSIZE 4
144         /* you are welcome to make this nice :) */
145         char str[7];
146         u16 i, j, y=STDOUT_BORDER_TOP, x=STDOUT_BORDER_LEFT;
147         u16 old_x, old_y;
148         struct kbrep *k;
149
150         while(1) {
151                 memset(str, '\0', 8);
152                 j=0;
153                 k = usb_hidkb_getChars();
154                 old_x = x; /* save actual x and y position for printing after the loop */
155                 old_y = y;
156                 for(i=0; k->keys[i]>0; i++) {
157                         unsigned char key = usb_hidkb_get_char_from_keycode(k->keys[i],
158                                         (k->mod & MOD_lshift) || (k->mod & MOD_rshift));
159                         /* no key or key not relevant? next, please. */
160                         if (key == 0)
161                                 continue;
162
163                         /* RETURN pressed? */
164                         if (key == '\n') {
165                                 x = STDOUT_BORDER_LEFT;
166                                 y += FONT_HEIGHT;
167                         /* TAB pressed? */
168                         } else if (key == '\t') {
169                                 x += (TABSIZE*FONT_WIDTH);
170
171                         /* BACKSPACE pressed? */
172                         } else if (key == '\r') {
173                                 /* TODO */
174
175                         /* now we have only printable characters left */
176                         } else {
177                                 x += FONT_WIDTH;
178                                 str[j] = key;
179                                 j++;
180                         }
181
182                         /* line full? break! */
183                         if(x > (STDOUT_BORDER_RIGHT-FONT_WIDTH)) {
184                                 x = STDOUT_BORDER_LEFT;
185                                 y += FONT_HEIGHT;
186                         }
187                         /* screen full? start again at top */
188                         if(y > (STDOUT_BORDER_BOTTOM-FONT_HEIGHT)) {
189                                 y = STDOUT_BORDER_TOP;
190                         }
191                 }
192                 if(j > 0) { /* when there was any printable stuff, show it */
193                         print_str_noscroll(old_x, old_y, str);
194                         printf("y: %d\n", y);
195                 }
196
197         }
198
199 #if 0
200         printf("===============================\n");
201
202         SHA1TestCases();
203
204         printf("bye, world!\n");
205 #endif
206
207         return 0;
208 }
209