SHARE
TWEET

Untitled

a guest Jan 24th, 2020 71 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  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. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Top