psx emulator
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

89 lines
2.2 KiB

  1. #include "boot.h"
  2. #include "cpu.h"
  3. #include "insn.h"
  4. #include "log.h"
  5. #include "psx.h"
  6. #include <assert.h>
  7. #include <stdlib.h>
  8. #include <stdio.h>
  9. #include <string.h>
  10. static const uint8_t MAGIC[0x10] = "PS-X EXE";
  11. static const uint8_t RESERVED[0x10] = {0};
  12. psx_header_t parse_psx_header(byte_arr_t *prgm)
  13. {
  14. psx_header_t header;
  15. // TODO: Convert asserts into recoverable error
  16. debug("Checking header struct size");
  17. assert(sizeof header == 0x38 - 0x10);
  18. debug("Checking program size is greater than header");
  19. assert(prgm->size >= 0x800);
  20. debug("Checking magic number in header");
  21. assert(memcmp(MAGIC, prgm->data, sizeof MAGIC) == 0);
  22. memcpy(&header, &prgm->data[sizeof MAGIC], sizeof header);
  23. debug("Checking file size in header matches program size");
  24. assert(header.size_file == prgm->size - 0x800);
  25. debug("Checking A34h region is zero");
  26. assert(memcmp(RESERVED, &prgm->data[0x38], sizeof RESERVED) == 0);
  27. return header;
  28. }
  29. uint32_t translate_addr(uint32_t addr)
  30. {
  31. if (addr >= 0xA0000000)
  32. {
  33. addr = addr - 0xA0000000;
  34. }
  35. else if (addr >= 0x80000000)
  36. {
  37. addr = addr - 0x80000000;
  38. }
  39. return addr;
  40. }
  41. void boot_psx_prgm(byte_arr_t *prgm)
  42. {
  43. debug("Parsing program header");
  44. psx_header_t header = parse_psx_header(prgm);
  45. debug("Program header");
  46. debug("size=%u bytes", header.size_file);
  47. debug("pc=%08x, gp=%08x, sp=%08x, fp=%08x", header.pc, header.gp, header.sp, header.fp);
  48. debug("data=%08x (%u bytes)", header.addr_data, header.size_data);
  49. debug("bss=%08x (%u bytes)", header.addr_bss, header.size_bss);
  50. debug("dest=%08x", header.addr_dest);
  51. cpu_t *cpu = malloc(sizeof *cpu);
  52. uint32_t start = translate_addr(header.addr_dest);
  53. assert(start + header.size_file < MAIN_RAM_SIZE);
  54. memcpy(&cpu->main_ram[start], &prgm->data[0x800], header.size_file);
  55. cpu->pc = header.pc;
  56. cpu->regs[REG_GP] = header.gp;
  57. cpu->regs[REG_SP] = header.sp;
  58. cpu->regs[REG_FP] = header.fp;
  59. psx_t psx = {header, cpu};
  60. while (1)
  61. {
  62. debug("Executing instruction at %08x", psx.cpu->pc);
  63. const uint32_t insn = cpu_read32(cpu, psx.cpu->pc);
  64. insn_execute(cpu, insn);
  65. psx.cpu->pc += 1;
  66. }
  67. }