From reading the data book it appears the 8080 handles interrupts like this:

  1. The interrupt source (external to the CPU) will set the CPU's interrupt pin.

  2. When the CPU acknowledges the interrupt, the interrupt source can put any opcode on the bus and the CPU will see it. (Most of the time they use the RST instruction.)

  3. The CPU executes that instruction. If it is RST, that is a equivalent to a CALL instruction to a fixed low memory location. It pushes the current PC on the stack. (See the [branch group][3] section).

  4. The code at the low memory location handles whatever the interrupt is trying to tell the program. When the handling is over, the RST will end with a RET call.

The game’s video hardware generates 2 interrupts which we will have to emulate in software, a end of frame and a middle of frame. Both execute at 60 Hz (60 times a second). 1/60 of a second is 16.6667 milliseconds.

I'll add a function to the 8080 emulator to facilitate interrupts:

   void GenerateInterrupt(State8080* state, int interrupt_num)    
    //perform "PUSH PC"    
       Push(state, (state->pc & 0xFF00) >> 8, (state->pc & 0xff));    

    //Set the PC to the low memory vector.    
    //This is identical to an "RST interrupt_num" instruction.    
    state->pc = 8 * interrupt_num;    

The platform code will have to implement a timer we can call (I'll just call it time() for now). The machine code will use that to give the 8080 emulator an interrupt. In the machine code, I'll call GenerateInterrupt when the timer goes off:

    while (!done)    

        if ( time() - lastInterrupt > 1.0/60.0)  //1/60 second has elapsed    
            //only do an interrupt if they are enabled    
            if (state->int_enable)    
                GenerateInterrupt(state, 2);    //interrupt 2    

                //Save the time we did this    
                lastInterrupt = time();    

There are some details about exactly how the 8080 actually handles interrupts that we aren't going to emulate. I believe this handling is going to be good enough for our purposes.

← Prev: buttons-and-ports   Next: cocoa-port-pt-1---setting-up-the-project →

Post questions or comments on Twitter @realemulator101, or if you find issues in the code, file them on the github repository.