Advertisement
Guest User

Untitled

a guest
Jan 24th, 2020
98
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.89 KB | None | 0 0
  1. class CHIP8 {
  2. public:
  3. typedef unsigned char reg_t; // 8-bit register datatype
  4. typedef unsigned char mem_t; // 8-bit memory datatype
  5. typedef unsigned short ptr_t; // 16-bit pointer datatype
  6. typedef unsigned short inst_t; // 16-bit instruction datatype
  7.  
  8. const inst_t *program; // stored program memory
  9. std::vector<mem_t> memory; // read/write data memory
  10. ptr_t program_counter;
  11. enum {nreg=16};
  12. reg_t V[nreg]; // registers
  13. ptr_t I; // memory pointer register
  14. bool done; // set to true when the program hits 0xFFFF instruction
  15.  
  16. // Set up a simulator to run this program, with this much memory, starting from this program address
  17. CHIP8(const inst_t *program_,ptr_t memory_length=100,ptr_t program_start=0)
  18. :program(program_),
  19. memory(memory_length),
  20. program_counter(program_start),
  21. I(0),
  22. done(false)
  23. {}
  24.  
  25. void error(const char *what) {
  26. fprintf(stderr,"CHIP-8 error: %s\n",what);
  27. done=true;
  28. }
  29.  
  30. // Execute one instruction
  31. void step(void) {
  32. inst_t fetch=program[program_counter++]; // the next instruction
  33. inst_t opcode=(fetch>>12)&0xF; // high bits
  34. inst_t X=(fetch>>8)&0xF; // destination register
  35. inst_t Y=(fetch>>4)&0xF; // optional other parts of instruction
  36. inst_t NN=(fetch)&0xFF;
  37. inst_t NNN=(fetch)&0xFF;
  38.  
  39. switch(opcode) {
  40. case 0x1: // jump
  41. program_counter = NNN;
  42. break;
  43. case 0x3:
  44. if (V[X] == NN) program_counter++;
  45. break;
  46. case 0x5: // cond
  47. if (V[X] == V[Y]) program_counter++;
  48. break;
  49. case 0x6: // const
  50. V[X] = NN;
  51. break;
  52. case 0x7: // const
  53. V[X] += NN;
  54. break;
  55. case 0x8: // math
  56. switch (fetch & 0xF) {
  57. case 0x4: V[X] += V[Y]; break; // add
  58. case 0x5:
  59. V[X] -= V[Y];
  60. if(V[X] - V[Y] < 0) {
  61. V[0xF] = 0;
  62. }
  63. else {
  64. V[0xF] = 1;
  65. }
  66. break; // subtract
  67. case 0x0: V[X] = V[Y]; break; // assign
  68. default: error("Unknown arithmetic instruction"); break;
  69. }
  70. break;
  71. case 0xA:
  72. I = NNN;
  73. break;
  74. case 0xF: // special functions
  75. if (NN==0xFA) { int r; std::cin>>r; V[X]=r; break; }
  76. if (NN==0xFD) { std::cout<<(int)V[X]<<"\n"; break; }
  77. if (NN==0xFF) { done=true; break; }
  78. if (NN==0x1E) {
  79. if (I+V[X] > 0xFFF) {
  80. V[0xF] = 1;
  81. }
  82. else {
  83. V[0xF] = 0;
  84. }
  85. I += V[X];
  86. break;
  87. }
  88. if (NN==0x55) { // dump
  89. unsigned int reg_num = 0;
  90. for(unsigned int i_offset = I; i_offset < X; ++i_offset) {
  91. memory[i_offset] = V[reg_num];
  92. reg_num++;
  93. }
  94. break;
  95. }
  96. if (NN==0x65) { // load
  97. unsigned int reg_num = 0;
  98. for(unsigned int i_offset = I; i_offset < X; ++i_offset) {
  99. V[reg_num] = memory[i_offset];
  100. reg_num++;
  101. }
  102. break;
  103. }
  104. // intentional fall-through here:
  105. default: error("unimplemented instruction"); break;
  106. }
  107. }
  108.  
  109. // Print the machine state (debugging)
  110. void print(void) {
  111. printf(" pc: %04x (%04x) V0=%02x V1=%02x V2=%02x V5=%02x VF=%02x\n",
  112. program_counter,program[program_counter],V[0],V[1],V[2],V[5],V[0xF]);
  113. }
  114. };
  115.  
  116.  
  117.  
  118.  
  119.  
  120.  
  121.  
  122.  
  123.  
  124.  
  125.  
  126. // Stored program, in program memory
  127. const CHIP8::inst_t instructions[]={
  128. 0xF2FA, // read input into V2 [LOOP BOUND]
  129. 0x6502, // V5 = 2 [LOOP COUNTER]
  130. 0x6101, // V1 = 1 - constant
  131. // 0xFaFD, // print V5 [LOOP START]
  132.  
  133.  
  134. 0xF065, // V0 = memeory[I]
  135. 0x8300, // V3 = V0
  136.  
  137. 0x3300, // V3 == 0?
  138. 0x1003, // jmp loop begin
  139.  
  140.  
  141. 0xF7FD, // Print V5
  142. 0x8750, // V7 = V5
  143. 0x8754, // V7 += V5 [LOOP2 COUNTER] [LOOP2 START]
  144.  
  145. 0x6001, // V0 = 1
  146. 0xF055, // Store V0 to memory @ I
  147. 0xF11E, // I++
  148.  
  149. 0x8870, // V8 = V7
  150. 0x8285, // V2 -= V8
  151. 0x8284, // V2 += V8
  152. 0x3F00, // VF == 0?
  153. 0x1009, // Jump to loop2 start
  154.  
  155. 0x7501, // V5++
  156.  
  157. 0x5520, // V5 == V2? yes -> skip next instruction | no -> loop
  158. 0x1003, // jump to loop beginning [LOOP END]
  159. 0xFFFF // end program
  160. };
  161.  
  162. long foo(void)
  163. {
  164. CHIP8 sim(instructions,1000,0);
  165. while (!sim.done) {
  166. sim.print();
  167. sim.step();
  168. }
  169. return 0;
  170. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement