/[pearpc]/src/main.cc
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /src/main.cc

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (show annotations)
Wed Sep 5 17:11:21 2007 UTC (16 years, 6 months ago) by dpavlin
File size: 12409 byte(s)
import upstream CVS
1 /*
2 * PearPC
3 * main.cc
4 *
5 * Copyright (C) 2003-2005 Sebastian Biallas (sb@biallas.net)
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 #include <cstdlib>
22 #include <cstring>
23 #include <exception>
24 #include <unistd.h>
25
26 #include "info.h"
27 #include "cpu/cpu.h"
28 //#include "cpu_generic/ppc_tools.h"
29 #include "debug/debugger.h"
30 #include "io/io.h"
31 #include "io/graphic/gcard.h"
32 #include "io/ide/ide.h"
33 #include "io/ide/cd.h"
34 #include "io/prom/prom.h"
35 #include "io/prom/promboot.h"
36 #include "io/prom/prommem.h"
37 #include "tools/atom.h"
38 #include "tools/data.h"
39 #include "tools/except.h"
40 #include "tools/snprintf.h"
41 #include "system/display.h"
42 #include "system/mouse.h"
43 #include "system/keyboard.h"
44 #include "system/sys.h"
45 #include "configparser.h"
46
47 #include "system/gif.h"
48 #include "system/ui/gui.h"
49
50 #include "ppc_font.h"
51 #include "ppc_img.h"
52 #include "ppc_button_changecd.h"
53
54 void changeCDFunc(void *p)
55 {
56 int *i = (int *)p;
57 IDEConfig *idecfg = ide_get_config(*i);
58
59 CDROMDevice *dev = (CDROMDevice *)idecfg->device;
60
61 dev->acquire();
62
63 if (dev->isLocked()) {
64 dev->release();
65
66 // sys_gui_messagebox("cdrom is locked!");
67 } else {
68 dev->setReady(false);
69 dev->release();
70 /*
71 * because we have set ready to false, no one can use
72 * the cdrom now (no medium present)
73 */
74 String fn;
75 if (sys_gui_open_file_dialog(fn, "title", "*.*", "alle", "testa", true)) {
76 dev->acquire();
77 ((CDROMDeviceFile *)dev)->changeDataSource(fn.contentChar());
78 dev->setReady(true);
79 dev->release();
80 } else {
81 /*
82 * the user picked no file / canceled the dialog.
83 * what's better now, to leave the old medium
84 * or to set no medium present?
85 * we choose the second option.
86 */
87 }
88 }
89 }
90
91 void initMenu()
92 {
93 /* IDEConfig *idecfg = ide_get_config(0);
94 if (idecfg->installed && idecfg->protocol == IDE_ATAPI) {
95 MemMapFile changeCDButton(ppc_button_changecd, sizeof ppc_button_changecd);
96 int *i = new int;
97 *i = 0;
98 gDisplay->insertMenuButton(changeCDButton, changeCDFunc, i);
99 }
100 idecfg = ide_get_config(1);
101 if (idecfg->installed && idecfg->protocol == IDE_ATAPI) {
102 MemMapFile changeCDButton(ppc_button_changecd, sizeof ppc_button_changecd);
103 int *i = new int;
104 *i = 1;
105 gDisplay->insertMenuButton(changeCDButton, changeCDFunc, i);
106 }
107 gDisplay->finishMenu();*/
108 }
109
110 static char *textlogo UNUSED = "\e[?7h\e[40m\e[2J\e[40m\n\n\n\n\n\e[0;1m"
111 "\e[24C\xda\xc4\xc4\xc4\xc4\xc4\xc4\xc4 "
112 "\xda\xc4\xc4\xc4\xc4\xc4\xc4\xc4 "
113 "\xda\xc4\xc4\xc4\xc4\xc4\xc4\n\e[24C\e[0m\xda\xc4\xc4 "
114 "\xda\xc4\xc4 \xda\xc4\xc4 \xda\xc4\xc4 \xda\xc4\xc4 "
115 "\xda\xc4\xc4\n\e[24C\e[1;30m\xda\xc4\xc4\xc4\xc4\xc4\xc4\xc4 "
116 "\xda\xc4\xc4\xc4\xc4\xc4\xc4\xc4 "
117 "\xda\xc4\xc4\n\e[24C\e[34m\xda\xc4\xc4\e[7C\xda\xc4\xc4\e[7C\xda\xc4\xc4 "
118 "\xda\xc4\xc4\n\e[24C\e[0;34m\xda\xc4\xc4\e[7C\xda\xc4\xc4\e[8C\xda\xc4\xc4\xc4\xc4\xc4\xc4\n\n";
119
120 static const vcp CONSOLE_BG = VC_BLACK;
121
122 void drawLogo()
123 {
124 MemMapFile img(ppc_img, sizeof ppc_img);
125 Gif g;
126 g.loadFromByteStream(img);
127 gDisplay->fillRGB(0, 0, gDisplay->mClientChar.width,
128 gDisplay->mClientChar.height, MK_RGB(0xff, 0xff, 0xff));
129 g.draw(gDisplay, (gDisplay->mClientChar.width-g.mWidth)/2, (gDisplay->mClientChar.height >= 600) ? (150-g.mHeight)/2 : 0);
130 gDisplay->setAnsiColor(VCP(VC_BLUE, CONSOLE_BG));
131 gDisplay->fillAllVT(VCP(VC_BLUE, CONSOLE_BG), ' ');
132 // gDisplay->print(textlogo);
133 gDisplay->setAnsiColor(VCP(VC_LIGHT(VC_BLUE), VC_TRANSPARENT));
134 gDisplay->print("\e[H"APPNAME" "APPVERSION" "COPYRIGHT"\n\n");
135 }
136
137 void tests()
138 {
139 /* while (true) {
140 DisplayEvent ev;
141 if (gDisplay->getEvent(ev)) {
142 if (ev.type == evMouse) {
143 gDisplay->printf("%x, %x ", ev.mouseEvent.relx, ev.mouseEvent.rely);
144 gDisplay->printf("%x\n", ev.mouseEvent.button1);
145 } else {
146 gDisplay->printf("%x %d\n", ev.keyEvent.keycode, ev.keyEvent.keycode);
147 }
148 }
149 }*/
150 }
151
152 #include "io/prom/forth.h"
153 void testforth()
154 {
155
156 #if 0
157 ForthVM vm;
158 gCPU.msr = MSR_IR | MSR_DR | MSR_FP;
159 // LocalFile in("test/test.f2", IOAM_READ, FOM_EXISTS);
160 // vm.interprete(in, in);
161 do {
162 try {
163 MemoryFile in(0);
164 char buf[1024];
165 fgets(buf, sizeof buf, stdin);
166 in.write(buf, strlen(buf));
167 in.seek(0);
168 vm.interprete(in, in);
169 } catch (const ForthException &fe) {
170 String res;
171 fe.reason(res);
172 ht_printf("exception: %y\n", &res);
173 }
174 } while (1);
175
176 #endif
177 }
178
179 /*
180 *
181 */
182 void usage()
183 {
184 ht_printf("usage: ppc configfile\n");
185 exit(1);
186 }
187
188 #ifdef main
189 // Get rid of stupid SDL main redefinitions
190 #undef main
191 extern "C" int SDL_main(int argc, char *argv[])
192 {
193 return 0;
194 }
195 #endif
196
197 int main(int argc, char *argv[])
198 {
199 if (argc != 2) {
200 usage();
201 }
202 setvbuf(stdout, 0, _IONBF, 0);
203
204 sys_gui_init();
205
206 if (sizeof(uint8) != 1) {
207 ht_printf("sizeof(uint8) == %d != 1\n", sizeof(uint8)); exit(-1);
208 }
209 if (sizeof(uint16) != 2) {
210 ht_printf("sizeof(uint16) == %d != 2\n", sizeof(uint16)); exit(-1);
211 }
212 if (sizeof(uint32) != 4) {
213 ht_printf("sizeof(uint32) == %d != 4\n", sizeof(uint32)); exit(-1);
214 }
215 if (sizeof(uint64) != 8) {
216 ht_printf("sizeof(uint64) == %d != 8\n", sizeof(uint64)); exit(-1);
217 }
218
219 #if defined(WIN32) || defined(__WIN32__)
220 #else
221 strncpy(gAppFilename, argv[0], sizeof gAppFilename);
222 #endif
223
224 if (!initAtom()) return 3;
225 if (!initData()) return 4;
226 if (!initOSAPI()) return 5;
227 try {
228 gConfig = new ConfigParser();
229 gConfig->acceptConfigEntryStringDef("ppc_start_resolution", "800x600x15");
230 gConfig->acceptConfigEntryIntDef("ppc_start_full_screen", 0);
231 gConfig->acceptConfigEntryIntDef("memory_size", 128*1024*1024);
232 gConfig->acceptConfigEntryIntDef("page_table_pa", 0x00300000);
233 gConfig->acceptConfigEntryIntDef("redraw_interval_msec", 20);
234 gConfig->acceptConfigEntryStringDef("key_compose_dialog", "F11");
235 gConfig->acceptConfigEntryStringDef("key_change_cd_0", "none");
236 gConfig->acceptConfigEntryStringDef("key_change_cd_1", "none");
237 gConfig->acceptConfigEntryStringDef("key_toggle_mouse_grab", "F12");
238 gConfig->acceptConfigEntryStringDef("key_toggle_full_screen", "Ctrl+Alt+Return");
239
240 prom_init_config();
241 io_init_config();
242 ppc_cpu_init_config();
243 debugger_init_config();
244
245 try {
246 LocalFile *config;
247 config = new LocalFile(argv[1]);
248 gConfig->loadConfig(*config);
249 delete config;
250 } catch (const Exception &e) {
251 String res;
252 e.reason(res);
253 ht_printf("%s: %y\n", argv[1], &res);
254 usage();
255 exit(1);
256 }
257
258 ht_printf("This program is free software; you can redistribute it and/or modify\n"
259 "it under the terms of the GNU General Public License version 2 as published by\n"
260 "the Free Software Foundation.\n"
261 "\n"
262 "This program is distributed in the hope that it will be useful,\n"
263 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
264 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
265 "GNU General Public License for more details.\n"
266 "\n"
267 "You should have received a copy of the GNU General Public License\n"
268 "along with this program; if not, write to the Free Software\n"
269 "Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA\n\n");
270
271
272 if (gConfig->getConfigInt("memory_size") < 64*1024*1024) {
273 ht_printf("%s: 'memory_size' must be >= 64MB.", argv[1]);
274 exit(1);
275 }
276 int msec = gConfig->getConfigInt("redraw_interval_msec");
277 if (msec < 10 || msec > 500) {
278 ht_printf("%s: 'redraw_interval_msec' must be between 10 and 500 (inclusive).", argv[1]);
279 exit(1);
280 }
281
282 String key_compose_dialog_string;
283 String key_toggle_mouse_grab_string;
284 String key_toggle_full_screen_string;
285 KeyboardCharacteristics keyConfig;
286 gConfig->getConfigString("key_compose_dialog", key_compose_dialog_string);
287 gConfig->getConfigString("key_toggle_mouse_grab", key_toggle_mouse_grab_string);
288 gConfig->getConfigString("key_toggle_full_screen", key_toggle_full_screen_string);
289 if (!SystemKeyboard::convertStringToKeycode(keyConfig.key_compose_dialog, key_compose_dialog_string)) {
290 ht_printf("%s: invalid '%s'\n", argv[1], "key_compose_dialog");
291 exit(1);
292 }
293 if (!SystemKeyboard::convertStringToKeycode(keyConfig.key_toggle_mouse_grab, key_toggle_mouse_grab_string)) {
294 ht_printf("%s: invalid '%s'\n", argv[1], "key_toggle_mouse_grab");
295 exit(1);
296 }
297 if (!SystemKeyboard::convertStringToKeycode(keyConfig.key_toggle_full_screen, key_toggle_full_screen_string)) {
298 ht_printf("%s: invalid '%s'\n", argv[1], "key_toggle_full_screen");
299 exit(1);
300 }
301
302
303 gcard_init_modes();
304
305 String chr;
306 DisplayCharacteristics gm;
307 bool fullscreen;
308 gConfig->getConfigString("ppc_start_resolution", chr);
309 fullscreen = gConfig->getConfigInt("ppc_start_full_screen");
310 if (!displayCharacteristicsFromString(gm, chr)) {
311 ht_printf("%s: invalid '%s'\n", argv[1], "ppc_start_resolution");
312 exit(1);
313 }
314 switch (gm.bytesPerPixel) {
315 /*
316 * Are we confusing bytesPerPixel with bitsPerPixel?
317 * Yes! And I am proud of it!
318 */
319 case 15:
320 gm.bytesPerPixel = 2;
321 break;
322 case 32:
323 gm.bytesPerPixel = 4;
324 break;
325 default:
326 ht_printf("%s: invalid depth in '%s'\n", argv[1], "ppc_start_resolution");
327 exit(1);
328 }
329 if (!gcard_finish_characteristic(gm)) {
330 ht_printf("%s: invalid '%s'\n", argv[1], "ppc_start_resolution");
331 exit(1);
332 }
333 gcard_add_characteristic(gm);
334
335
336 /*
337 * begin hardware init
338 */
339
340 if (!ppc_init_physical_memory(gConfig->getConfigInt("memory_size"))) {
341 ht_printf("cannot initialize memory.\n");
342 exit(1);
343 }
344 if (!ppc_cpu_init()) {
345 ht_printf("cpu_init failed! Out of memory?\n");
346 exit(1);
347 }
348
349 initUI(APPNAME" "APPVERSION, gm, msec, keyConfig, fullscreen);
350
351 io_init();
352
353 gcard_init_host_modes();
354 gcard_set_mode(gm);
355
356 if (fullscreen) gDisplay->setFullscreenMode(true);
357
358 MemMapFile font(ppc_font, sizeof ppc_font);
359 // FIXME: ..
360 if (gDisplay->mClientChar.height >= 600) {
361 int width = (gDisplay->mClientChar.width-40)/8;
362 int height = (gDisplay->mClientChar.height-170)/15;
363 if (!gDisplay->openVT(width, height, (gDisplay->mClientChar.width-width*8)/2, 150, font)) {
364 ht_printf("Can't open virtual terminal.\n");
365 exit(1);
366 }
367 } else {
368 if (!gDisplay->openVT(77, 25, 12, 100, font)) {
369 ht_printf("Can't open virtual terminal.\n");
370 exit(1);
371 }
372 }
373
374 initMenu();
375 drawLogo();
376
377 // now gDisplay->printf works
378 gDisplay->printf("CPU: PVR=%08x\n", ppc_cpu_get_pvr(0));
379 gDisplay->printf("%d MiB RAM\n", ppc_get_memory_size() / (1024*1024));
380
381 tests();
382
383 // initialize initial paging (for prom)
384 uint32 PAGE_TABLE_ADDR = gConfig->getConfigInt("page_table_pa");
385 gDisplay->printf("initializing initial page table at %08x\n", PAGE_TABLE_ADDR);
386
387 // 256 Kbytes Pagetable, 2^15 Pages, 2^12 PTEGs
388 if (!ppc_prom_set_sdr1(PAGE_TABLE_ADDR+0x03, false)) {
389 ht_printf("internal error setting sdr1.\n");
390 return 1;
391 }
392
393 // clear pagetable
394 if (!ppc_dma_set(PAGE_TABLE_ADDR, 0, 256*1024)) {
395 ht_printf("cannot access page table.\n");
396 return 1;
397 }
398
399 // init prom
400 prom_init();
401
402 // lock pagetable
403 for (uint32 pa = PAGE_TABLE_ADDR; pa < (PAGE_TABLE_ADDR + 256*1024); pa += 4096) {
404 if (!prom_claim_page(pa)) {
405 ht_printf("cannot claim page table memory.\n");
406 exit(1);
407 }
408 }
409
410 testforth();
411
412 if (!prom_load_boot_file()) {
413 ht_printf("cannot find boot file.\n");
414 return 1;
415 }
416
417 // this was your last chance to visit the config..
418 delete gConfig;
419
420 ppc_cpu_map_framebuffer(IO_GCARD_FRAMEBUFFER_PA_START, IO_GCARD_FRAMEBUFFER_EA);
421
422 gDisplay->print("now starting client...");
423 gDisplay->setAnsiColor(VCP(VC_WHITE, CONSOLE_BG));
424
425 ppc_cpu_run();
426
427 io_done();
428
429 } catch (const std::exception &e) {
430 ht_printf("main() caught exception: %s\n", e.what());
431 return 1;
432 } catch (const Exception &e) {
433 String res;
434 e.reason(res);
435 ht_printf("main() caught exception: %y\n", &res);
436 return 1;
437 }
438
439 doneUI();
440 doneOSAPI();
441 doneData();
442 doneAtom();
443 return 0;
444 }

  ViewVC Help
Powered by ViewVC 1.1.26