upse_r3000_abstract.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. /*
  2. * UPSE: the unix playstation sound emulator.
  3. *
  4. * Filename: upse_r3000_abstract.c
  5. * Purpose: libupse: r3K abstract implementation factory
  6. *
  7. * Copyright (c) 2007 William Pitcock <nenolod@sacredspiral.co.uk>
  8. * Portions copyright (c) 1999-2002 Pcsx Team
  9. * Portions copyright (c) 2004 "Xodnizel"
  10. *
  11. * UPSE is free software, released under the GNU General Public License,
  12. * version 2.
  13. *
  14. * A copy of the GNU General Public License, version 2, is included in
  15. * the UPSE source kit as COPYING.
  16. *
  17. * UPSE is offered without any warranty of any kind, explicit or implicit.
  18. */
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <string.h>
  22. #include "upse-internal.h"
  23. upse_r3000_cpu_registers_t upse_r3000_cpu_regs;
  24. int psxInit()
  25. {
  26. if (upse_ps1_memory_init() == -1)
  27. return -1;
  28. return upse_r3000_cpu_init();
  29. }
  30. void psxReset()
  31. {
  32. upse_r3000_cpu_reset();
  33. upse_ps1_memory_reset();
  34. memset(&upse_r3000_cpu_regs, 0, sizeof(upse_r3000_cpu_regs));
  35. upse_r3000_cpu_regs.pc = 0xbfc00000; // Start in bootstrap
  36. upse_r3000_cpu_regs.CP0.r[12] = 0x10900000; // COP0 enabled | BEV = 1 | TS = 1
  37. upse_r3000_cpu_regs.CP0.r[15] = 0x00000002; // PRevID = Revision ID, same as R3000A
  38. upse_ps1_hal_reset();
  39. upse_ps1_bios_init();
  40. /* start up the bios */
  41. if (upse_has_custom_bios())
  42. psxExecuteBios();
  43. }
  44. void psxShutdown()
  45. {
  46. upse_ps1_memory_shutdown();
  47. upse_ps1_bios_shutdown();
  48. upse_r3000_cpu_shutdown();
  49. SPUclose();
  50. }
  51. void psxException(u32 code, u32 bd)
  52. {
  53. // Set the Cause
  54. upse_r3000_cpu_regs.CP0.n.Cause = code;
  55. #ifdef PSXCPU_LOG
  56. if (bd)
  57. PSXCPU_LOG("bd set\n");
  58. #endif
  59. // Set the EPC & PC
  60. if (bd)
  61. {
  62. upse_r3000_cpu_regs.CP0.n.Cause |= 0x80000000;
  63. upse_r3000_cpu_regs.CP0.n.EPC = (upse_r3000_cpu_regs.pc - 4);
  64. }
  65. else
  66. upse_r3000_cpu_regs.CP0.n.EPC = (upse_r3000_cpu_regs.pc);
  67. if (upse_r3000_cpu_regs.CP0.n.Status & 0x400000)
  68. upse_r3000_cpu_regs.pc = 0xbfc00180;
  69. else
  70. upse_r3000_cpu_regs.pc = 0x80000080;
  71. // Set the Status
  72. upse_r3000_cpu_regs.CP0.n.Status = (upse_r3000_cpu_regs.CP0.n.Status & ~0x3f) | ((upse_r3000_cpu_regs.CP0.n.Status & 0xf) << 2);
  73. if (!upse_has_custom_bios())
  74. upse_ps1_bios_exception();
  75. }
  76. void psxBranchTest()
  77. {
  78. if ((upse_r3000_cpu_regs.cycle - psxNextsCounter) >= psxNextCounter)
  79. psxRcntUpdate();
  80. if (psxHu32(0x1070) & psxHu32(0x1074))
  81. {
  82. if ((upse_r3000_cpu_regs.CP0.n.Status & 0x401) == 0x401)
  83. {
  84. psxException(0x400, 0);
  85. }
  86. }
  87. }
  88. void psxExecuteBios()
  89. {
  90. while (upse_r3000_cpu_regs.pc != 0x80030000)
  91. upse_r3000_cpu_execute_block();
  92. }