Example #1
0
 public void notifyRead(int address) {
   if (cpu.isFlashBusy) {
     triggerAccessViolation("Flash read not allowed while BUSY flag set");
     return;
   }
   if (DEBUG) {
     if (wait == false && currentWriteMode == WriteMode.WRITE_BLOCK) {
       log("Reading flash prohibited. Would read 0x3fff!!!");
       log("CPU PC=$" + Utils.hex(cpu.getPC(), 4) + " read address $" + Utils.hex(address, 4));
     }
   }
 }
Example #2
0
  private void triggerAccessViolation(String reason) {
    logw(
        WarningType.EXECUTION,
        "Access violation: " + reason + ". PC=$" + Utils.hex(cpu.getPC(), 4));

    statusreg |= ACCVIFG;
    if (cpu.getSFR().isIEBitsSet(SFR.IE1, ACCVIE)) {
      cpu.flagInterrupt(NMI_VECTOR, this, true);
    }
  }
Example #3
0
  public void write(int address, int value, boolean word, long cycles) {
    if (address == offset) {
      if ((value >> 8) == 0x5a) {
        wdtctl = value & 0xff;
        if (DEBUG)
          log("Wrote to WDTCTL: " + Utils.hex8(wdtctl) + " from $" + Utils.hex(cpu.getPC(), 4));

        // Is it on?
        wdtOn = (value & 0x80) == 0;
        //        boolean lastACLK = sourceACLK;
        sourceACLK = (value & WDTSSEL) != 0;
        // scheduleTimer should use the current delay, so update delay each time
        // issue: if WDTCNTCL is not active the timer should be recalculated but an new timer is
        // scheduled
        // if ((value & WDTCNTCL) != 0) {
        // Clear timer => reset the delay
        delay = DELAY[value & WDTISx];
        // }
        timerMode = (value & WDTMSEL) != 0;
        // Start it if it should be started!
        if (wdtOn) {
          if (DEBUG) log("Setting WDTCNT to count: " + delay);
          scheduleTimer();
        } else {
          // Stop it and remember current "delay" left!
          wdtTrigger.remove();
        }
      } else {
        // Trigger reset!!
        logw(
            WarningType.EXECUTION,
            "illegal write to WDTCTL ("
                + value
                + ") from $"
                + Utils.hex(cpu.getPC(), 4)
                + " - reset!!!!");
        cpu.flagInterrupt(resetVector, this, true);
      }
    }
  }
Example #4
0
 @Override
 public String getAddressAsString(int addr) {
   return Utils.hex20(addr);
 }
Example #5
0
  public void flashWrite(int address, int data, AccessMode dataMode) {
    int wait_time = -1;

    if (locked) {
      if (DEBUG) {
        log("Write to flash blocked because of LOCK flag.");
      }
      return;
    }

    if (cpu.isFlashBusy || wait == false) {
      if (!((mode & BLKWRT) != 0 && wait)) {
        triggerAccessViolation("Flash write prohbited while BUSY=1 or WAIT=0");
        return;
      }
    }

    switch (currentWriteMode) {
      case ERASE_SEGMENT:
        int a_area_start[] = new int[1];
        int a_area_end[] = new int[1];
        getSegmentRange(address, a_area_start, a_area_end);
        int area_start = a_area_start[0];
        int area_end = a_area_end[0];

        if (DEBUG) {
          log(
              "Segment erase @"
                  + Utils.hex(address, 4)
                  + ": erasing area "
                  + Utils.hex(area_start, 4)
                  + "-"
                  + Utils.hex(area_end, 4));
        }
        for (int i = area_start; i < area_end; i++) {
          memory[i] = 0xff;
        }
        waitFlashProcess(SEGMENT_ERASE_TIME);
        break;

      case ERASE_MAIN:
        if (!main_range.isInRange(address)) {
          return;
        }
        for (int i = main_range.start; i < main_range.end; i++) {
          memory[i] = 0xff;
        }
        waitFlashProcess(MASS_ERASE_TIME);
        break;

      case ERASE_ALL:
        for (int i = main_range.start; i < main_range.end; i++) {
          memory[i] = 0xff;
        }
        for (int i = info_range.start; i < main_range.end; i++) {
          memory[i] = 0xff;
        }
        waitFlashProcess(MASS_ERASE_TIME);
        break;
      case WRITE_SINGLE:
      case WRITE_BLOCK:
        if (currentWriteMode == WriteMode.WRITE_BLOCK) {
          wait = false;
          // TODO: Register target block and verify all writes stay in the same
          // block. What does the real hardware on random writes?!?
          if (blockwriteCount == 0) {
            wait_time = BLOCKWRITE_FIRST_TIME;
            if (DEBUG) {
              log("Flash write in block mode started @" + Utils.hex(address, 4));
            }
            if (addressInFlash(cpu.getPC())) {
              logw(
                  WarningType.EXECUTION,
                  "Oops. Block write access only allowed when executing from RAM.");
            }
          } else {
            wait_time = BLOCKWRITE_TIME;
          }
        } else {
          wait_time = WRITE_TIME;
        }
        /* Flash memory allows clearing bits only */
        memory[address] &= data & 0xff;
        if (dataMode != AccessMode.BYTE) {
          memory[address + 1] &= (data >> 8) & 0xff;
          if (dataMode == AccessMode.WORD20) {
            /* TODO should the write really write the full word? CHECK THIS */
            memory[address + 2] &= (data >> 16) & 0xff;
            memory[address + 3] &= (data >> 24) & 0xff;
          }
        }
        if (DEBUG) {
          log(
              "Writing $"
                  + Utils.hex20(data)
                  + " to $"
                  + Utils.hex(address, 4)
                  + " ("
                  + dataMode.bytes
                  + " bytes)");
        }
        waitFlashProcess(wait_time);
        break;
    }
  }