decoder.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. /*
  2. MSP430 Emulator
  3. Copyright (C) 2020 Rudolf Geosits (rgeosits@live.esu.edu)
  4. "MSP430 Emulator" is free software: you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation, either version 3 of the License, or
  7. (at your option) any later version.
  8. "MSP430 Emulator" is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program. If not, see <https://www.gnu.org/licenses/>.
  14. */
  15. #include "decoder.h"
  16. // ##########+++ CPU Fetch Cycle +++##########
  17. uint16_t fetch(Emulator *emu)
  18. {
  19. Cpu *cpu = emu->cpu;
  20. uint16_t word, *p;
  21. p = (get_addr_ptr(cpu->pc));
  22. word = *p;
  23. cpu->pc += 2;
  24. return word;
  25. }
  26. // ##########+++ CPU Decode Cycle +++##########
  27. void decode(Emulator *emu, uint16_t instruction, bool disassemble)
  28. {
  29. Cpu *cpu = emu->cpu;
  30. Debugger *debugger = emu->debugger;
  31. int done = 0;
  32. uint8_t FormatId;
  33. memset(debugger->mnemonic, 0, sizeof debugger->mnemonic);
  34. FormatId = (uint8_t)(instruction >> 12);
  35. if (FormatId == 0x1)
  36. {
  37. // format II (single operand) instruction
  38. decode_formatII(emu, instruction, disassemble);
  39. }
  40. else if (FormatId >= 0x2 && FormatId <= 3)
  41. {
  42. // format III (jump) instruction
  43. decode_formatIII(emu, instruction, disassemble);
  44. }
  45. else if (FormatId >= 0x4)
  46. {
  47. // format I (two operand) instruction
  48. decode_formatI(emu, instruction, disassemble);
  49. }
  50. else
  51. {
  52. char inv[100] = {0};
  53. sprintf(inv, "%04X\t[INVALID INSTRUCTION]\n", instruction);
  54. print_console(emu, inv);
  55. printf("%s", inv);
  56. //cpu->pc -= 2;
  57. cpu->running = false;
  58. debugger->debug_mode = true;
  59. }
  60. }
  61. // Constant Generator
  62. int16_t run_constant_generator(uint8_t source, uint8_t as_flag)
  63. {
  64. int16_t generated_constant = 0;
  65. switch (source)
  66. {
  67. case 2:
  68. { /* Register R2/SR/CG1 */
  69. switch (as_flag)
  70. {
  71. case 0b10:
  72. { /* +4, bit processing */
  73. generated_constant = 4;
  74. break;
  75. }
  76. case 0b11:
  77. { /* +8, bit processing */
  78. generated_constant = 8;
  79. break;
  80. }
  81. default:
  82. {
  83. printf("Invalid as_flag for CG1\n");
  84. }
  85. }
  86. break;
  87. }
  88. // Register R3/CG2
  89. case 3:
  90. {
  91. switch (as_flag)
  92. {
  93. case 0b00:
  94. { /* 0, word processing */
  95. generated_constant = 0;
  96. break;
  97. }
  98. case 0b01:
  99. { /* +1 */
  100. generated_constant = 1;
  101. break;
  102. }
  103. case 0b10:
  104. { /* +2, bit processing */
  105. generated_constant = 2;
  106. break;
  107. }
  108. case 0b11:
  109. { /* -1, word processing */
  110. generated_constant = -1;
  111. break;
  112. }
  113. default:
  114. {
  115. printf("Invalid as_flag for CG2\n");
  116. }
  117. }
  118. break;
  119. }
  120. default:
  121. {
  122. printf("Invalid source register for constant generation.\n");
  123. }
  124. }
  125. return generated_constant;
  126. }