uInt8 M6532::peek()

in atari_py/ale_interface/src/emucore/M6532.cxx [118:218]


uInt8 M6532::peek(uInt16 addr)
{
  switch(addr & 0x07)
  {
    case 0x00:    // Port A I/O Register (Joystick)
    {
      uInt8 value = 0x00;

      if(myConsole.controller(Controller::Left).read(Controller::One))
        value |= 0x10;
      if(myConsole.controller(Controller::Left).read(Controller::Two))
        value |= 0x20;
      if(myConsole.controller(Controller::Left).read(Controller::Three))
        value |= 0x40;
      if(myConsole.controller(Controller::Left).read(Controller::Four))
        value |= 0x80;

      if(myConsole.controller(Controller::Right).read(Controller::One))
        value |= 0x01;
      if(myConsole.controller(Controller::Right).read(Controller::Two))
        value |= 0x02;
      if(myConsole.controller(Controller::Right).read(Controller::Three))
        value |= 0x04;
      if(myConsole.controller(Controller::Right).read(Controller::Four))
        value |= 0x08;

      return value;
    }

    case 0x01:    // Port A Data Direction Register 
    {
      return myDDRA;
    }

    case 0x02:    // Port B I/O Register (Console switches)
    {
      return myConsole.switches().read();
    }

    case 0x03:    // Port B Data Direction Register
    {
      return myDDRB;
    }

    case 0x04:    // Timer Output
    case 0x06:
    {
      uInt32 cycles = mySystem->cycles() - 1;
      uInt32 delta = cycles - myCyclesWhenTimerSet;
      Int32 timer = (Int32)myTimer - (Int32)(delta >> myIntervalShift) - 1;

      // See if the timer has expired yet?
      if(timer >= 0)
      {
        return (uInt8)timer; 
      }
      else
      {
        timer = (Int32)(myTimer << myIntervalShift) - (Int32)delta - 1;

        if((timer <= -2) && !myTimerReadAfterInterrupt)
        {
          // Indicate that timer has been read after interrupt occured
          myTimerReadAfterInterrupt = true;
          myCyclesWhenInterruptReset = mySystem->cycles();
        }

        if(myTimerReadAfterInterrupt)
        {
          Int32 offset = myCyclesWhenInterruptReset - 
              (myCyclesWhenTimerSet + (myTimer << myIntervalShift));

          timer = (Int32)myTimer - (Int32)(delta >> myIntervalShift) - offset;
        }

        return (uInt8)timer;
      }
    }

    case 0x05:    // Interrupt Flag
    case 0x07:
    {
      uInt32 cycles = mySystem->cycles() - 1;
      uInt32 delta = cycles - myCyclesWhenTimerSet;
      Int32 timer = (Int32)myTimer - (Int32)(delta >> myIntervalShift) - 1;

      if((timer >= 0) || myTimerReadAfterInterrupt)
        return 0x00;
      else
        return 0x80;
    }

    default:
    {    
#ifdef DEBUG_ACCESSES
      ale::Logger::Error << "BAD M6532 Peek: " << hex << addr << endl;
#endif
      return 0;
    }
  }
}