upse_ps1_executive.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. /*
  2. * UPSE: the unix playstation sound emulator.
  3. *
  4. * Filename: upse_ps1_executive.c
  5. * Purpose: libupse: PS1 application executive (lowlevel "Kernel")
  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 "upse-internal.h"
  20. /* tracing */
  21. #ifdef UPSE_TRACE
  22. # define _TRACE(...) _MESSAGE("TRACE", __VA_ARGS__)
  23. #else
  24. # define _TRACE(...) {}
  25. #endif
  26. #define _CALL(id, idN) do { _TRACE("call<%s> %s<%p> [0x%x]", #id, idN[call], id[call], call); id[call](); } while(0)
  27. #define _UNIMPLEMENTED(id, idN) do { _WARN("call<%s> %s<%p> [0x%x]", #id, idN[call], id[call], call); } while(0)
  28. static void upse_ps1_executive_dummy(void)
  29. {
  30. upse_r3000_cpu_regs.pc = upse_r3000_cpu_regs.GPR.n.ra;
  31. psxBranchTest();
  32. }
  33. static void upse_ps1_executive_run_bios_A0(void)
  34. {
  35. u32 call = upse_r3000_cpu_regs.GPR.n.t1 & 0xff;
  36. if (biosA0[call])
  37. _CALL(biosA0, biosA0n);
  38. else
  39. _UNIMPLEMENTED(biosA0, biosA0n);
  40. psxBranchTest();
  41. }
  42. static void upse_ps1_executive_run_bios_B0(void)
  43. {
  44. u32 call = upse_r3000_cpu_regs.GPR.n.t1 & 0xff;
  45. if (biosB0[call])
  46. _CALL(biosB0, biosB0n);
  47. else
  48. _UNIMPLEMENTED(biosB0, biosB0n);
  49. psxBranchTest();
  50. }
  51. static void upse_ps1_executive_run_bios_C0()
  52. {
  53. u32 call = upse_r3000_cpu_regs.GPR.n.t1 & 0xff;
  54. if (biosC0[call])
  55. _CALL(biosC0, biosC0n);
  56. else
  57. _UNIMPLEMENTED(biosC0, biosC0n);
  58. psxBranchTest();
  59. }
  60. static void upse_ps1_executive_bootstrap(void)
  61. { // 0xbfc00000
  62. }
  63. typedef struct
  64. {
  65. u32 _pc0;
  66. u32 gp0;
  67. u32 t_addr;
  68. u32 t_size;
  69. u32 d_addr;
  70. u32 d_size;
  71. u32 b_addr;
  72. u32 b_size;
  73. u32 s_addr;
  74. u32 s_size;
  75. u32 _sp, _fp, _gp, ret, base;
  76. } upse_packed_t upse_ps1_executive_exec_record_t;
  77. static void upse_ps1_executive_task_switch(void)
  78. {
  79. upse_ps1_executive_exec_record_t *header = (upse_ps1_executive_exec_record_t *) PSXM(upse_r3000_cpu_regs.GPR.n.s0);
  80. //SysPrintf("ExecRet %x: %x\n", upse_r3000_cpu_regs.GPR.n.s0, header->ret);
  81. upse_r3000_cpu_regs.GPR.n.ra = BFLIP32(header->ret);
  82. upse_r3000_cpu_regs.GPR.n.sp = BFLIP32(header->_sp);
  83. upse_r3000_cpu_regs.GPR.n.s8 = BFLIP32(header->_fp);
  84. upse_r3000_cpu_regs.GPR.n.gp = BFLIP32(header->_gp);
  85. upse_r3000_cpu_regs.GPR.n.s0 = BFLIP32(header->base);
  86. upse_r3000_cpu_regs.GPR.n.v0 = 1;
  87. upse_r3000_cpu_regs.pc = upse_r3000_cpu_regs.GPR.n.ra;
  88. }
  89. void (*psxHLEt[256])(void) =
  90. {
  91. upse_ps1_executive_dummy,
  92. upse_ps1_executive_run_bios_A0,
  93. upse_ps1_executive_run_bios_B0,
  94. upse_ps1_executive_run_bios_C0,
  95. upse_ps1_executive_bootstrap,
  96. upse_ps1_executive_task_switch
  97. };