1 /*---------------------------------------------------------------------------*
2   Project:  Revolution DVD error handling demo
3   File:     errorhandling.c
4 
5   Copyright 2006 Nintendo.  All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law.  They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13   $Log: errorhandling.c,v $
14   Revision 1.5  07/28/2006 02:01:17  ooizumi
15   Disabled handling reset switch code.
16 
17   Revision 1.4  06/10/2006 00:49:44  ooizumi
18   Disabled the default disc fatal screen.
19 
20   Revision 1.3  02/28/2006 21:17:19  ooizumi
21   Removed audio streaming functions.
22   Modified several comments.
23 
24   Revision 1.1  2006/01/17 02:43:50  hiratsu
25   Initial check in.
26 
27 
28     5     02/06/04 16:23 Hashida
29     Removed warnings.
30 
31     4     02/02/18 17:20 Hashida
32     Added DVDGetCurrentDiskID.
33     Fixed a bug that the demo crashes when executing DVDChangeDisk twice.
34 
35     3     1/03/02 5:48p Hashida
36     Added change disk.
37 
38     2     6/16/01 5:50a Hashida
39     Changed so that error status and play address are shown only when it's
40     succeeded.
41 
42     1     6/15/01 9:03p Hashida
43     Initial revision.
44 
45   $NoKeywords: $
46  *---------------------------------------------------------------------------*/
47 
48 /*---------------------------------------------------------------------------*
49  * This demo illustrates how to handle errors. See __refresh_status() for
50  * the actual error handling code!
51  *---------------------------------------------------------------------------*/
52 
53 #include <demo.h>
54 #include <revolution.h>
55 #include <demo/DEMOWin.h>
56 #include <string.h>
57 #include <stdio.h>
58 #include "selectfile.h"
59 
60 /*---------------------------------------------------------------------------*
61  * DVD definitions
62  *---------------------------------------------------------------------------*/
63 #define DVD_BUFFER_SIZE             0xf00000
64 static void*                        Buffer;
65 
66 static DVDFileInfo                  FileInfo;
67 static volatile BOOL                FileInfoIsInUse = FALSE;
68 
69 static DVDDiskID                    DiskID;
70 
71 /*---------------------------------------------------------------------------*
72  * Misc
73  *---------------------------------------------------------------------------*/
74 #define MIN(x, y)                   ((x) < (y)? (x):(y))
75 
76 
77 /*---------------------------------------------------------------------------*
78  * Data to pass from command issuing routines to status printing routine.
79  *---------------------------------------------------------------------------*/
80 enum{
81     COMMAND_READ,
82     COMMAND_SEEK,
83     COMMAND_GET_ERROR_STATUS,
84     COMMAND_CHANGE_DISK
85 };
86 
87 typedef struct
88 {
89     u32             command;
90     s32             readLength;
91 } CommandBlockData;
92 
93 static CommandBlockData         Data;
94 
95 
96 /*---------------------------------------------------------------------------*
97  * Messages for errors
98  *---------------------------------------------------------------------------*/
99 typedef struct
100 {
101     char*           line[6];
102 } Message;
103 
104 // Error messages. XXX Caution: Subject to change.
105 Message ErrorMessages[] = {
106     {"Please insert the disc for xxx.", "", "", "", "", ""},
107     {"This disc is not for xxx.", "Please insert the disc for xxx.", "", "", "", ""},
108     {"The disc could not be read.", "", "Please read the NINTENDO REVOLUTION",
109      "Instruction Booklet for more information", "", ""},
110     {"An error has occurred.", "", "Turn the power OFF and check", "the NINTENDO REVOLUTION",
111      "Instruction Booklet for", "further instructions."},
112     {"Please insert the next disc.", "", "", "", "", ""},
113 };
114 
115 enum{
116     MESSAGE_NO_DISK = 0,
117     MESSAGE_WRONG_DISK,
118     MESSAGE_RETRY_ERROR,
119     MESSAGE_FATAL_ERROR,
120     MESSAGE_CHANGE_DISK
121 };
122 
123 
124 /*---------------------------------------------------------------------------*
125  * Prototypes
126  *---------------------------------------------------------------------------*/
127 static void InitWindows(void);
128 
129 static void __status_refresh(DEMOWinInfo *handle);
130 
131 static void Run_Demo(void);
132 
133 static void MNU_read(DEMOWinMenuInfo *menu, u32 item, u32 *result);
134 static void MNU_seek(DEMOWinMenuInfo *menu, u32 item, u32 *result);
135 static void MNU_cancel(DEMOWinMenuInfo *menu, u32 item, u32 *result);
136 static void MNU_change_disk(DEMOWinMenuInfo *menu, u32 item, u32 *result);
137 static void MNU_get_disk_id(DEMOWinMenuInfo *menu, u32 item, u32 *result);
138 
139 static void MNU_pick_number(DEMOWinMenuInfo *menu, u32 item, u32 *result);
140 
141 /*---------------------------------------------------------------------------*
142  * Main Control Menu Stuff!
143  *---------------------------------------------------------------------------*/
144 DEMOWinMenuItem control_menu_items[] =
145 {
146     { "ISSUE COMMAND",              DEMOWIN_ITM_SEPARATOR,  NULL,                   NULL },
147     { "  DVDRead",                  DEMOWIN_ITM_NONE,       MNU_read,               NULL },
148     { "  DVDSeek",                  DEMOWIN_ITM_NONE,       MNU_seek,               NULL },
149     { "  DVDCancel",                DEMOWIN_ITM_NONE,       MNU_cancel,             NULL },
150     { "  DVDChangeDisk",            DEMOWIN_ITM_NONE,       MNU_change_disk,        NULL },
151     { "  DVDGetCurrentDiskID",      DEMOWIN_ITM_NONE,       MNU_get_disk_id,        NULL },
152     { "",                           DEMOWIN_ITM_TERMINATOR, NULL,                   NULL }
153 };
154 
155 DEMOWinMenuInfo control_menu =
156 {
157    "DVD Error Handling Demo",     // title
158     NULL,                   // window handle
159     control_menu_items,     // list of menu items
160     50,                     // max num of items to display at a time
161     DEMOWIN_MNU_NONE,       // attribute flags?
162 
163     // user callbacks for misc menu operations
164     NULL, NULL, NULL, NULL,
165     // private menu info members; do not touch
166     0, 0, 0, 0, 0
167 };
168 DEMOWinMenuInfo *control_menu_ptr;
169 
170 DEMOWinMenuItem number_menu_items[] =
171 {
172     { "255",                        DEMOWIN_ITM_EOF,        MNU_pick_number,        NULL },
173     { "0",                          DEMOWIN_ITM_EOF,        MNU_pick_number,        NULL },
174     { "1",                          DEMOWIN_ITM_EOF,        MNU_pick_number,        NULL },
175     { "2",                          DEMOWIN_ITM_EOF,        MNU_pick_number,        NULL },
176     { "3",                          DEMOWIN_ITM_EOF,        MNU_pick_number,        NULL },
177     { "4",                          DEMOWIN_ITM_EOF,        MNU_pick_number,        NULL },
178     { "5",                          DEMOWIN_ITM_EOF,        MNU_pick_number,        NULL },
179     { "6",                          DEMOWIN_ITM_EOF,        MNU_pick_number,        NULL },
180     { "7",                          DEMOWIN_ITM_EOF,        MNU_pick_number,        NULL },
181     { "8",                          DEMOWIN_ITM_EOF,        MNU_pick_number,        NULL },
182     { "",                           DEMOWIN_ITM_TERMINATOR, NULL,                   NULL }
183 };
184 DEMOWinMenuInfo number_menu =
185 {
186    "Pick next disk number", // title
187     NULL,                   // window handle
188     number_menu_items,     // list of menu items
189     10,                     // max num of items to display at a time
190     DEMOWIN_MNU_NONE,       // attribute flags?
191 
192     // user callbacks for misc menu operations
193     NULL, NULL, NULL, NULL,
194     // private menu info members; do not touch
195     0, 0, 0, 0, 0
196 };
197 
198 /*---------------------------------------------------------------------------*
199  * Debug and Status window stuff!
200  *---------------------------------------------------------------------------*/
201 DEMOWinInfo *debug_win;     // debug window
202 DEMOWinInfo *status_win;    // status window
203 DEMOWinInfo *errmsg_win;    // error message window
204 
205 
206  /*---------------------------------------------------------------------------*
207     Name:               InitWindows
208 
209     Description:        Initialize windows
210 
211     Arguments:          none
212 
213     Returns:            none
214  *---------------------------------------------------------------------------*/
InitWindows(void)215 static void InitWindows(void)
216 {
217     DEMOWinInfo *p;
218 
219     control_menu_ptr = DEMOWinCreateMenuWindow(&control_menu, 20, 20);
220     p = control_menu_ptr->handle;
221 
222     // Initialize a window for showing status of DVD commands
223     // By passing "__status_refresh" as the last argument, the window system
224     // calls "__status_refresh" once every frame. We use this function to
225     // handle errors in this demo.
226     status_win = DEMOWinCreateWindow((u16)(p->x2+5), p->y1, 620, (u16)(p->y1+100),
227                                      "Status", 0, __status_refresh);
228 
229     // Initialize a window for debug output
230     debug_win  = DEMOWinCreateWindow((u16)(p->x2+5), (u16)(p->y1+105), 620, 434,
231                                      "Debug", 1024, NULL);
232 
233     // Initialize a window for showing error message
234     errmsg_win = DEMOWinCreateWindow(120, 150, 520, 250,
235                                      "Error message", 0, NULL);
236 
237     // Open status and debug windows. We don't open error message window until
238     // we hit an error.
239     DEMOWinOpenWindow(debug_win);
240     DEMOWinOpenWindow(status_win);
241 
242     // Tell the pointer to the debug window to the "file select" system
243     InitSelectFile(debug_win);
244 }
245 
246  /*---------------------------------------------------------------------------*
247     Name:               __status_refresh
248 
249     Description:        This is the error handling part. This function is called
250                         once every frame.
251 
252     Arguments:          handle              Window handle for the status window
253 
254     Returns:            none
255  *---------------------------------------------------------------------------*/
__status_refresh(DEMOWinInfo * handle)256 static void __status_refresh(DEMOWinInfo *handle)
257 {
258     static u32          counter;
259     s32                 message;
260     u32                 i;
261     CommandBlockData    *data;
262 
263 
264     // Clear status window (we only use the first two rows)
265     DEMOWinClearRow(handle, 0);
266     DEMOWinClearRow(handle, 1);
267 
268     // We use "user data" as the information of the command that was issued
269     // last.
270     data = DVDGetUserData((DVDCommandBlock*)&FileInfo);
271 
272     if (data)
273     {
274         // If it's a read command, show the progress
275         if (data->command == COMMAND_READ)
276         {
277             DEMOWinPrintfXY(handle, 0,  0, "Now loading....%3d%%(%d/%d)",
278                             100*DVDGetTransferredSize(&FileInfo)/data->readLength,
279                             DVDGetTransferredSize(&FileInfo), data->readLength);
280         }
281     }
282 
283     message = -1;
284 
285     // This part is for debugging purpose. Show the drive's status on status
286     // window.
287     switch(DVDGetDriveStatus())
288     {
289       case DVD_STATE_END:
290         FileInfoIsInUse = FALSE;
291         DEMOWinPrintfXY(handle, 0,  1, "Command finished");
292         break;
293       case DVD_STATE_FATAL_ERROR:
294         DEMOWinPrintfXY(handle, 0,  1, "Fatal error occurred");
295         message = MESSAGE_FATAL_ERROR;
296         break;
297       case DVD_STATE_BUSY:
298         break;
299       case DVD_STATE_NO_DISK:
300         DEMOWinPrintfXY(handle, 0,  1, "No disk");
301         message = MESSAGE_NO_DISK;
302         break;
303       case DVD_STATE_WRONG_DISK:
304         DEMOWinPrintfXY(handle, 0,  1, "Wrong disk");
305         message = MESSAGE_WRONG_DISK;
306         break;
307       case DVD_STATE_RETRY:
308         DEMOWinPrintfXY(handle, 0,  1, "Please retry");
309         message = MESSAGE_RETRY_ERROR;
310         break;
311       case DVD_STATE_MOTOR_STOPPED:
312         DEMOWinPrintfXY(handle, 0,  1, "Ready to replace");
313         message = MESSAGE_CHANGE_DISK;
314         break;
315     }
316 
317     // If necessary, launch error message window to show the error message to
318     // the user.
319     if (message >= 0)
320     {
321         DEMOWinOpenWindow(errmsg_win);
322         counter = (counter+1) % 60;
323         for (i = 0; i < 6; i++)
324         {
325             if (counter < 45)
326             {
327                 DEMOWinPrintfXY(errmsg_win, 0, (u16)i, ErrorMessages[message].line[i]);
328             }
329             else
330             {
331                 DEMOWinClearRow(errmsg_win, (u16)i);
332             }
333         }
334     }
335     else
336     {
337         DEMOWinCloseWindow(errmsg_win);
338     }
339 
340 #if 0
341     // temporary disabled until STM is implemented to firmware
342     if (OSGetResetSwitchState())
343     {
344         OSReport("reset is pressed\n");
345 
346         while (OSGetResetSwitchState())
347             ;
348 
349         OSReport("reset is released\n");
350 
351         OSRestart(3);
352     }
353 #endif
354 
355 } // end __status_refresh()
356 
357 
358  /*---------------------------------------------------------------------------*
359     Name:               MNU_cancel
360 
361     Description:        Issue DVDCancel. This function is called when DVDCancel
362                         is selected in the control window.
363 
364     Arguments:          menu, item, result      unused
365 
366     Returns:            none
367  *---------------------------------------------------------------------------*/
MNU_cancel(DEMOWinMenuInfo * menu,u32 item,u32 * result)368 static void MNU_cancel(DEMOWinMenuInfo *menu, u32 item, u32 *result)
369 {
370 #pragma unused(menu, item, result)
371     DVDCancelAsync((DVDCommandBlock*)&FileInfo, NULL);
372 }
373 
374 
readCallback(s32 result,DVDFileInfo * fileInfo)375 static void readCallback(s32 result, DVDFileInfo* fileInfo)
376 {
377     #pragma unused(fileInfo)
378 
379     if (result == DVD_RESULT_FATAL_ERROR)
380         return;
381 
382     OSReport("read finished\n");
383 }
384 
385  /*---------------------------------------------------------------------------*
386     Name:               MNU_read
387 
388     Description:        Issue DVDRead, after letting the user to select a file
389                         to read.
390 
391     Arguments:          menu                Winmenuinfo for control window
392                         item, result        unused
393 
394     Returns:            none
395  *---------------------------------------------------------------------------*/
MNU_read(DEMOWinMenuInfo * menu,u32 item,u32 * result)396 static void MNU_read(DEMOWinMenuInfo *menu, u32 item, u32 *result)
397 {
398 #pragma unused(item)
399 #pragma unused(result)
400     s32             length;
401     char*           file;
402 
403     // Avoid using the same FileInfo/CommandBlock at the same time.
404     if (FileInfoIsInUse)
405     {
406         return;
407     }
408 
409     DEMOWinLogPrintf(debug_win, "\nIssuing a read...\n");
410     DEMOWinLogPrintf(debug_win, "Press A to choose a file to read or change directory.\nPress B to exit.\n");
411 
412     // Launch a window to let the user to select a file.
413     // The return value is the pointer to the selected file.
414     file = SelectFile(menu->handle);
415 
416     DVDOpen(file, &FileInfo);
417     // If the size of the file is larger than the buffer size, we only read
418     // the first DVD_BUFFER_SIZE bytes.
419     length = (s32)OSRoundUp32B(MIN(DVDGetLength(&FileInfo), DVD_BUFFER_SIZE));
420 
421     // Pass information to __status_refresh()
422     Data.command = COMMAND_READ;
423     Data.readLength = length;
424     DVDSetUserData((DVDCommandBlock*)&FileInfo, (void*)&Data);
425 
426     FileInfoIsInUse = TRUE;
427     DVDReadAsync(&FileInfo, Buffer, length, 0, readCallback);
428 
429 }
430 
431  /*---------------------------------------------------------------------------*
432     Name:               MNU_seek
433 
434     Description:        Issue DVDSeek, after letting the user to select a file
435                         to seek to.
436 
437     Arguments:          menu                Winmenuinfo for control window
438                         item, result        unused
439 
440     Returns:            none
441  *---------------------------------------------------------------------------*/
MNU_seek(DEMOWinMenuInfo * menu,u32 item,u32 * result)442 static void MNU_seek(DEMOWinMenuInfo *menu, u32 item, u32 *result)
443 {
444 #pragma unused(item)
445 #pragma unused(result)
446     char*           file;
447 
448     // Avoid using the same FileInfo/CommandBlock at the same time.
449     if (FileInfoIsInUse)
450     {
451         return;
452     }
453 
454     DEMOWinLogPrintf(debug_win, "\nIssuing a seek...\n");
455     DEMOWinLogPrintf(debug_win, "Press A to choose a file to seek to or change directory.\nPress B to exit.\n");
456 
457     // Launch a window to let the user to select a file.
458     // The return value is the pointer to the selected file.
459     file = SelectFile(menu->handle);
460 
461     DVDOpen(file, &FileInfo);
462 
463     // Pass information to __status_refresh()
464     Data.command = COMMAND_SEEK;
465     DVDSetUserData((DVDCommandBlock*)&FileInfo, (void*)&Data);
466 
467     FileInfoIsInUse = TRUE;
468     DVDSeekAsync(&FileInfo, 0, NULL);
469 
470 }
471 
472 
MNU_pick_number(DEMOWinMenuInfo * menu,u32 item,u32 * result)473 static void MNU_pick_number(DEMOWinMenuInfo *menu, u32 item, u32 *result)
474 {
475 #pragma unused (menu)
476     *result = (item == 0)? 0xff : item - 1;
477 
478 } // end __select_file
479 
480 
PickNumber(DEMOWinInfo * handle)481 static u32 PickNumber(DEMOWinInfo *handle)
482 {
483     u32             val = 0;
484 
485     DEMOWinSetWindowColor(handle, DEMOWIN_COLOR_CAPTION,
486                           50, 50, 50, 255);
487 
488     DEMOWinCreateMenuWindow(&number_menu, (u16)(handle->x2-10), (u16)(handle->y1+24));
489     val = DEMOWinMenu(&number_menu);
490     DEMOWinDestroyMenuWindow(&number_menu);
491 
492     DEMOWinSetWindowColor(handle, DEMOWIN_COLOR_RESET, 0, 0, 0, 0);
493 
494     return val;
495 }
496 
497  /*---------------------------------------------------------------------------*
498     Name:               MNU_change_disk
499 
500     Description:        Issue DVDChangeDisk
501 
502     Arguments:          menu                Winmenuinfo for control window
503                         item, result        unused
504 
505     Returns:            none
506  *---------------------------------------------------------------------------*/
MNU_change_disk(DEMOWinMenuInfo * menu,u32 item,u32 * result)507 static void MNU_change_disk(DEMOWinMenuInfo *menu, u32 item, u32 *result)
508 {
509 #pragma unused(menu, item, result)
510     u32                     n;
511 
512     // Avoid using the same FileInfo/CommandBlock at the same time.
513     if (FileInfoIsInUse)
514     {
515         return;
516     }
517 
518     // Pass information to __status_refresh()
519     Data.command = COMMAND_CHANGE_DISK;
520     DVDSetUserData((DVDCommandBlock*)&FileInfo, (void*)&Data);
521 
522     n = PickNumber(menu->handle);
523 
524     OSReport("number: %d\n", n);
525 
526     memcpy(&DiskID, DVDGetCurrentDiskID(), sizeof(DVDDiskID));
527     DiskID.diskNumber = (u8)n;      // BCD (0x00 ... 1st disk, 0x01 ... 2nd disk)
528 
529     FileInfoIsInUse = TRUE;
530     DVDChangeDiskAsync((DVDCommandBlock*)&FileInfo, &DiskID, NULL);
531 }
532 
changeDiskCallback(s32 result,DVDCommandBlock * commandBlock)533 static void changeDiskCallback(s32 result, DVDCommandBlock* commandBlock)
534 {
535 #pragma unused(result, commandBlock)
536 }
537 
538  /*---------------------------------------------------------------------------*
539     Name:               MNU_get_disk_id
540 
541     Description:        Show disk id
542 
543     Arguments:          menu                Winmenuinfo for control window
544                         item, result        unused
545 
546     Returns:            none
547  *---------------------------------------------------------------------------*/
MNU_get_disk_id(DEMOWinMenuInfo * menu,u32 item,u32 * result)548 static void MNU_get_disk_id(DEMOWinMenuInfo *menu, u32 item, u32 *result)
549 {
550 #pragma unused(menu, item, result)
551     DVDDiskID*              id;
552 
553     id = DVDGetCurrentDiskID();
554 
555     DEMOWinLogPrintf(debug_win, "====Current disk ID====\n");
556     DEMOWinLogPrintf(debug_win, "   Game Name ... %-4.4s\n", id->gameName);
557     DEMOWinLogPrintf(debug_win, "   Company ..... %-2.2s\n", id->company);
558     DEMOWinLogPrintf(debug_win, "   Disk # ...... %x\n",     id->diskNumber);
559     DEMOWinLogPrintf(debug_win, "   Game ver .... %x\n",     id->gameVersion);
560 }
561 
562  /*---------------------------------------------------------------------------*
563     Name:               Run_Demo
564 
565     Description:        Main loop of the demo.
566 
567     Arguments:          none
568 
569     Returns:            none
570  *---------------------------------------------------------------------------*/
Run_Demo(void)571 static void Run_Demo(void)
572 {
573     DEMOWinPadInfo pad;
574 
575     DEMOWinLogPrintf(debug_win, "-------------------------------\n");
576     DEMOWinLogPrintf(debug_win, "DVD error handling sample\n");
577     DEMOWinLogPrintf(debug_win, "-------------------------------\n");
578     DEMOWinLogPrintf(debug_win, "- Stick Up/Down to move cursor\n");
579     DEMOWinLogPrintf(debug_win, "- Button A to select an item\n");
580     DEMOWinLogPrintf(debug_win, "- Button B to exit a menu\n");
581     DEMOWinLogPrintf(debug_win, "While you are executing a command, open cover, make no disk,\n");
582     DEMOWinLogPrintf(debug_win, "put other disks to see how to handle errors\n");
583 
584     while(1)
585     {
586         // Launch control window. This function returns when B is pressed.
587         DEMOWinMenu(control_menu_ptr);
588 
589         DEMOWinLogPrintf(debug_win, "-------------------------------------------\n");
590         DEMOWinLogPrintf(debug_win, "\nUse Stick Up/Down to scroll debug buffer.\n");
591         DEMOWinLogPrintf(debug_win, "\nHit Start to resume the demo.\n");
592 
593         DEMOBeforeRender();
594         DEMOWinRefresh();
595         DEMODoneRender();
596         DEMOWinPadRead(&pad);
597 
598         // Let the user to scroll the debug window. Press start button to
599         // go to the top of the outer loop and open the control window again.
600         while(1)
601         {
602 
603             DEMOWinPadRead(&pad);
604 
605             if (pad.pads[0].stickY < -50)
606             {
607                 DEMOWinScrollWindow(debug_win, DEMOWIN_SCROLL_DOWN);
608                 if (pad.pads[0].triggerLeft > 150)
609                 {
610                     DEMOWinScrollWindow(debug_win, DEMOWIN_SCROLL_DOWN);
611                     DEMOWinScrollWindow(debug_win, DEMOWIN_SCROLL_DOWN);
612                 }
613             }
614             else if (pad.pads[0].stickY > 50)
615             {
616                 DEMOWinScrollWindow(debug_win, DEMOWIN_SCROLL_UP);
617                 if (pad.pads[0].triggerLeft > 150)
618                 {
619                     DEMOWinScrollWindow(debug_win, DEMOWIN_SCROLL_UP);
620                     DEMOWinScrollWindow(debug_win, DEMOWIN_SCROLL_UP);
621                 }
622 
623             }
624             else if (pad.changed_button[0] & PAD_BUTTON_START)
625             {
626                 DEMOWinScrollWindow(debug_win, DEMOWIN_SCROLL_HOME);
627                 // get out of the inner loop
628                 break;
629             }
630 
631             DEMOBeforeRender();
632             DEMOWinRefresh();
633             DEMODoneRender();
634 
635 
636         } // debug buffer scroll loop
637 
638     } // forever loop
639 
640 
641 } // end Init_Player_Windows()
642 
643 
644 
645 
main(void)646 void main(void)
647 {
648     void*           arenaLo;
649 
650     arenaLo = OSGetArenaLo();
651     Buffer = arenaLo;
652     OSSetArenaLo((void*)((u32)arenaLo + DVD_BUFFER_SIZE));
653 
654     // disabled the default disc fatal screen
655     DVDSetAutoFatalMessaging(FALSE);
656 
657     // clear user data
658     DVDSetUserData((DVDCommandBlock*)&FileInfo, (void*)NULL);
659 
660     DEMOInit(NULL);
661 
662     OSReport("Disk number is %x\n", DVDGetCurrentDiskID()->diskNumber);
663 
664     AIInit(NULL);
665 
666     OSReport("AIInit done\n");
667 
668     DEMOWinInit();
669 
670     OSReport("DEMOWinInit done\n");
671 
672     InitWindows();
673 
674     OSReport("InitWindows done\n");
675 
676     Run_Demo();
677 
678 } // end main
679