/[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

Annotation of /src/main.cc

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (hide annotations)
Wed Sep 5 17:11:21 2007 UTC (16 years, 7 months ago) by dpavlin
File size: 12409 byte(s)
import upstream CVS
1 dpavlin 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