An emulator, assembler, and disassembler for the Sega Game Gear
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.
 
 
 
 
 

93 lines
2.3 KiB

  1. /* Copyright (C) 2014-2015 Ben Kurtovic <ben.kurtovic@gmail.com>
  2. Released under the terms of the MIT License. See LICENSE for details. */
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include "util.h"
  6. #if defined __APPLE__
  7. #include <mach/mach_time.h>
  8. #elif defined __linux__
  9. #include <time.h>
  10. #ifndef CLOCK_MONOTONIC
  11. #error "Unsupported operating system or compiler."
  12. #endif
  13. #else
  14. #error "Unsupported operating system or compiler."
  15. #endif
  16. #define NS_PER_SEC 1000000000
  17. /*
  18. Convert a BCD-encoded hexadecimal number to decimal.
  19. */
  20. uint8_t bcd_decode(uint8_t num)
  21. {
  22. return ((num >> 4) * 10) + (num & 0x0F);
  23. }
  24. /*
  25. Return monotonic time, in nanoseconds.
  26. */
  27. uint64_t get_time_ns()
  28. {
  29. #if defined __APPLE__
  30. static mach_timebase_info_data_t tb_info;
  31. if (tb_info.denom == 0)
  32. mach_timebase_info(&tb_info);
  33. // Apple's docs pretty much say "screw overflow" here...
  34. return mach_absolute_time() * tb_info.numer / tb_info.denom;
  35. #elif defined __linux__
  36. struct timespec spec;
  37. clock_gettime(CLOCK_MONOTONIC, &spec);
  38. return spec.tv_sec * NS_PER_SEC + spec.tv_nsec;
  39. #endif
  40. }
  41. /*
  42. Return the name of the region encoded by the given region code.
  43. The given code should not be larger than one nibble. NULL is returned if
  44. the region code is invalid.
  45. Region code information is taken from:
  46. http://www.smspower.org/Development/ROMHeader
  47. */
  48. const char* region_code_to_string(uint8_t code)
  49. {
  50. switch (code) {
  51. case 3: return "SMS Japan";
  52. case 4: return "SMS Export";
  53. case 5: return "GG Japan";
  54. case 6: return "GG Export";
  55. case 7: return "GG International";
  56. default: return NULL;
  57. }
  58. }
  59. /*
  60. Return the region code that encodes the given region name.
  61. 0 is returned if the name is not known. This is not a valid region code.
  62. */
  63. uint8_t region_string_to_code(const char *name)
  64. {
  65. if (!strcmp(name, "SMS ")) {
  66. name += 4;
  67. if (strcmp(name, "Japan"))
  68. return 3;
  69. if (strcmp(name, "Export"))
  70. return 4;
  71. } else if (!strcmp(name, "GG ")) {
  72. name += 3;
  73. if (strcmp(name, "Japan"))
  74. return 5;
  75. if (strcmp(name, "Export"))
  76. return 6;
  77. if (strcmp(name, "International"))
  78. return 7;
  79. }
  80. return 0;
  81. }