Advertisement
EliteAnax17

crash.c

May 17th, 2017
95
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.68 KB | None | 0 0
  1. #include "global.h"
  2. #include "main.h"
  3. #include "sound.h"
  4. #include "songs.h"
  5. #include "task.h"
  6. #include "sprite.h"
  7. #include "palette.h"
  8. #include "menu.h"
  9. #include "string_util.h"
  10.  
  11. extern void WaitForVBlank(void);
  12.  
  13. extern u8 gUnknown_0839F63C[];
  14. extern u8 gUnknown_0839F5FC[]; //palette
  15.  
  16. // exceptions
  17. enum
  18. {
  19. TASK_OVERFLOW
  20. };
  21.  
  22. struct CrashExceptionInfo
  23. {
  24. u8 *string;
  25. };
  26.  
  27. struct CrashScreen
  28. {
  29. u32 registers[13]; // r0-r12
  30. void (* returnPointer)(void); // lr
  31. u32 *stackPointer; // sp
  32. u32 statusRegister;
  33. u8 exception;
  34. };
  35.  
  36. const u8 gCrashScreenHeaderText[] = _("An error has occured. Please pass these\ndetails below to the developers:");
  37. const u8 gCrashScreenRegisterR0[] = _("r0: ");
  38. const u8 gCrashScreenRegisterR1[] = _("r1: ");
  39. const u8 gCrashScreenRegisterR2[] = _("r2: ");
  40. const u8 gCrashScreenRegisterR3[] = _("r3: ");
  41. const u8 gCrashScreenRegisterR4[] = _("r4: ");
  42. const u8 gCrashScreenRegisterR5[] = _("r5: ");
  43. const u8 gCrashScreenRegisterR6[] = _("r6: ");
  44. const u8 gCrashScreenRegisterR7[] = _("r7: ");
  45. const u8 gCrashScreenRegisterR8[] = _("r8: ");
  46. const u8 gCrashScreenRegisterR9[] = _("r9: ");
  47. const u8 gCrashScreenRegisterR10[] = _("r10: ");
  48. const u8 gCrashScreenRegisterR11[] = _("r11: ");
  49. const u8 gCrashScreenRegisterR12[] = _("r12: ");
  50. const u8 gCrashScreenRegisterLR[] = _("lr: ");
  51.  
  52. const u8 gCrashScreenPlaceholderText[] = _("{STR_VAR_1}");
  53.  
  54. const u8 gCrashScreenExceptionTaskOverflow[] = _("TASK OVERFLOW");
  55.  
  56. EWRAM_DATA u32 CrashException = {0};
  57. EWRAM_DATA struct CrashScreen gCrashScreenInfo = {0};
  58.  
  59. void DoCrashScreen(void);
  60.  
  61. /*static void MainCB(void)
  62. {
  63. RunTasks();
  64. AnimateSprites();
  65. BuildOamBuffer();
  66. UpdatePaletteFade();
  67. }*/
  68.  
  69. // copy the registers and current information to the struct.
  70. __attribute__((naked))
  71. void Crash(void)
  72. {
  73. asm(".syntax unified\n\
  74. push {lr}\n\
  75. mov lr, r12\n\
  76. push {lr}\n\
  77. mov lr, r11\n\
  78. push {lr}\n\
  79. mov lr, r10\n\
  80. push {lr}\n\
  81. mov lr, r9\n\
  82. push {lr}\n\
  83. mov lr, r8\n\
  84. push {r0-r7, lr}\n\
  85. pop {r0}\n\
  86. ldr r1, CrashPool\n\
  87. str r0, [r1]\n\
  88. ldr r0, CrashPool\n\
  89. pop {r1}\n\
  90. str r1, [r0, #0x4]\n\
  91. pop {r1}\n\
  92. str r1, [r0, #0x8]\n\
  93. pop {r1}\n\
  94. str r1, [r0, #0xC]\n\
  95. pop {r1}\n\
  96. str r1, [r0, #0x10]\n\
  97. pop {r1}\n\
  98. str r1, [r0, #0x14]\n\
  99. pop {r1}\n\
  100. str r1, [r0, #0x18]\n\
  101. pop {r1}\n\
  102. str r1, [r0, #0x1C]\n\
  103. pop {r1}\n\
  104. str r1, [r0, #0x20]\n\
  105. pop {r1}\n\
  106. str r1, [r0, #0x24]\n\
  107. pop {r1}\n\
  108. str r1, [r0, #0x28]\n\
  109. pop {r1}\n\
  110. str r1, [r0, #0x2C]\n\
  111. pop {r1}\n\
  112. str r1, [r0, #0x30]\n\
  113. pop {r1}\n\
  114. str r1, [r0, #0x34]\n\
  115. mov r1, sp\n\
  116. str r1, [r0, #0x38] @ the stack pointer is equal to its state from the previous function after the push/pops used to preserve the registers and lr.\n\
  117. .align 2\n\
  118. bx pc @ switch to ARM\n\
  119. nop @ it takes 1 cycle to switch.\n\
  120. .arm\n\
  121. mscr r1, cpsr\n\
  122. str r1, [r0, #0x3C]\n\
  123. bl DoCrashScreen\n\
  124. .align 2, 0\n\
  125. CrashPool: .4byte gCrashScreenInfo\n\
  126. .syntax divided");
  127. }
  128.  
  129. #define WIN_RANGE_(a, b) (((a) << 8) + (b))
  130.  
  131. void DoCrashScreen(void)
  132. {
  133. gCrashScreenInfo.exception = CrashException;
  134.  
  135. PlayBGM(BGM_STOP);
  136. {
  137. u8 *addr;
  138. u32 size;
  139.  
  140. addr = (u8 *)VRAM;
  141. size = 0x18000;
  142. while (1)
  143. {
  144. DmaFill16(3, 0, addr, 0x1000);
  145. addr += 0x1000;
  146. size -= 0x1000;
  147. if (size <= 0x1000)
  148. {
  149. DmaFill16(3, 0, addr, size);
  150. break;
  151. }
  152. }
  153. DmaClear32(3, OAM, OAM_SIZE);
  154. DmaClear16(3, PLTT, PLTT_SIZE);
  155. ResetPaletteFade();
  156. SetUpWindowConfig(&gWindowConfig_81E71B4);
  157. MultistepInitMenuWindowBegin(&gWindowConfig_81E71B4);
  158. while(!MultistepInitMenuWindowContinue()) // don't return!
  159. ;
  160. LoadPalette(gUnknown_0839F5FC, 0x80, 0x40);
  161. CpuCopy16(gUnknown_0839F63C, (void *)0x0600BEE0, 0x40);
  162. }
  163. MenuDrawTextWindow(0, 0, 29, 19);
  164. MenuPrint(gCrashScreenHeaderText, 1, 1);
  165. MenuPrint(gCrashScreenRegisterR0, 1, 5);
  166. MenuPrint(gCrashScreenRegisterR1, 1, 7);
  167. MenuPrint(gCrashScreenRegisterR2, 1, 9);
  168. MenuPrint(gCrashScreenRegisterR3, 1, 11);
  169. MenuPrint(gCrashScreenRegisterR4, 1, 13);
  170. MenuPrint(gCrashScreenRegisterR5, 1, 15);
  171. MenuPrint(gCrashScreenRegisterR6, 1, 17);
  172.  
  173. // print r0.
  174. ConvertIntToHexStringN(gStringVar1, gCrashScreenInfo.registers[0], STR_CONV_MODE_LEADING_ZEROS, 8);
  175. MenuPrint(gCrashScreenPlaceholderText, 4, 5);
  176. ConvertIntToHexStringN(gStringVar1, gCrashScreenInfo.registers[1], STR_CONV_MODE_LEADING_ZEROS, 8);
  177. MenuPrint(gCrashScreenPlaceholderText, 4, 7);
  178. ConvertIntToHexStringN(gStringVar1, gCrashScreenInfo.registers[2], STR_CONV_MODE_LEADING_ZEROS, 8);
  179. MenuPrint(gCrashScreenPlaceholderText, 4, 9);
  180. ConvertIntToHexStringN(gStringVar1, gCrashScreenInfo.registers[3], STR_CONV_MODE_LEADING_ZEROS, 8);
  181. MenuPrint(gCrashScreenPlaceholderText, 4, 11);
  182. ConvertIntToHexStringN(gStringVar1, gCrashScreenInfo.registers[4], STR_CONV_MODE_LEADING_ZEROS, 8);
  183. MenuPrint(gCrashScreenPlaceholderText, 4, 13);
  184. ConvertIntToHexStringN(gStringVar1, gCrashScreenInfo.registers[5], STR_CONV_MODE_LEADING_ZEROS, 8);
  185. MenuPrint(gCrashScreenPlaceholderText, 4, 15);
  186. ConvertIntToHexStringN(gStringVar1, gCrashScreenInfo.registers[6], STR_CONV_MODE_LEADING_ZEROS, 8);
  187. MenuPrint(gCrashScreenPlaceholderText, 4, 17);
  188.  
  189. MenuPrint(gCrashScreenRegisterR7, 11, 5);
  190. MenuPrint(gCrashScreenRegisterR8, 11, 7);
  191. MenuPrint(gCrashScreenRegisterR9, 11, 9);
  192. MenuPrint(gCrashScreenRegisterR10, 11, 11);
  193. MenuPrint(gCrashScreenRegisterR11, 11, 13);
  194. MenuPrint(gCrashScreenRegisterR12, 11, 15);
  195. MenuPrint(gCrashScreenRegisterLR, 11, 17);
  196.  
  197. ConvertIntToHexStringN(gStringVar1, gCrashScreenInfo.registers[7], STR_CONV_MODE_LEADING_ZEROS, 8);
  198. MenuPrint(gCrashScreenPlaceholderText, 14, 5);
  199. ConvertIntToHexStringN(gStringVar1, gCrashScreenInfo.registers[8], STR_CONV_MODE_LEADING_ZEROS, 8);
  200. MenuPrint(gCrashScreenPlaceholderText, 14, 7);
  201. ConvertIntToHexStringN(gStringVar1, gCrashScreenInfo.registers[9], STR_CONV_MODE_LEADING_ZEROS, 8);
  202. MenuPrint(gCrashScreenPlaceholderText, 14, 9);
  203. ConvertIntToHexStringN(gStringVar1, gCrashScreenInfo.registers[10], STR_CONV_MODE_LEADING_ZEROS, 8);
  204. MenuPrint(gCrashScreenPlaceholderText, 14, 11);
  205. ConvertIntToHexStringN(gStringVar1, gCrashScreenInfo.registers[11], STR_CONV_MODE_LEADING_ZEROS, 8);
  206. MenuPrint(gCrashScreenPlaceholderText, 14, 13);
  207. ConvertIntToHexStringN(gStringVar1, gCrashScreenInfo.registers[12], STR_CONV_MODE_LEADING_ZEROS, 8);
  208. MenuPrint(gCrashScreenPlaceholderText, 14, 15);
  209. ConvertIntToHexStringN(gStringVar1, (u32)gCrashScreenInfo.returnPointer, STR_CONV_MODE_LEADING_ZEROS, 8);
  210. MenuPrint(gCrashScreenPlaceholderText, 14, 17);
  211.  
  212. REG_WIN1H = WIN_RANGE(0, 240);
  213. REG_WIN1V = WIN_RANGE_(0, 240);
  214. while(1)
  215. {
  216. WaitForVBlank();
  217. }
  218. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement