Sketch works on Nano, but not D1 Mini

I've written a rotary encoder demo sketch that works perfectly on a Nano using pins D2 and D3, but when I try to run it on a D1 Mini, using pins D1 and D2, I get this repeatedly over the serial monitor (at 115600):

 ets Jan  8 2013,rst cause:2, boot mode:(3,6)

load 0x4010f000, len 1384, room 16 
tail 8
chksum 0x2d
csum 0x2d
v8b899c12
~ld

The D1 Mini works fine on other sketches. I know it's something dumb, but I just can't see it. Here's the sketch:

const int aPIN = 1;                     // encoder pins
const int bPIN = 2;

const byte encoderType = 0;             // encoder with equal # of detents & pulses per rev
//const byte encoderType = 1;             // encoder with  pulses = detents/2. pick one, commment out the other

const int THRESH =(4-(2*encoderType));  // transitions needed to recognize a tick - type 0 = 4, type 1 = 2

const byte ZEERO = 0x80;                // byte data type doesn't do negative

volatile int currentValue = 0;
int oldValue = 0;
byte CURRENT;                           // the current state of the switches
byte INDEX = 15;                        // Index into lookup state table
byte TOTAL = 0;

// Encoder state table - there are 16 possible transitions between interrupts

int ENCTABLE[]  = {0,1,-1,0,-1,0,0,1,1,0,0,-1,0,-1,1,0};

void setup() {

  Serial.begin(9600);

  pinMode(aPIN, INPUT_PULLUP);          // set up encoder pins as INPUT-PULLUP
  pinMode(bPIN, INPUT_PULLUP);

  attachInterrupt(digitalPinToInterrupt(aPIN), Encoder, CHANGE);
  attachInterrupt(digitalPinToInterrupt(bPIN), Encoder, CHANGE);
}

void loop() {

  if(currentValue != oldValue) {        // serial print current value when it changes
    Serial.println(currentValue);
    oldValue = currentValue;
  }
}

void Encoder() {                        // pin change interrupts service routine. interrupts
                                        //     automatically disabled during execution

  INDEX     = INDEX << 2;               // Shift previous state left 2 bits (0 in)
  if(digitalRead (aPIN)) bitSet(INDEX,0); // If aPIN is high, set INDEX bit 0
  if(digitalRead (bPIN)) bitSet(INDEX,1); // If bPIN is high, set INDEX bit 1
  CURRENT = INDEX & 3;                  // CURRENT is the two low-order bits of INDEX
  INDEX &= 15;                          // Mask out all but prev and current

// INDEX is now a four-bit index into the 16-byte ENCTABLE state table

  TOTAL += ENCTABLE[INDEX];             //Accumulate transitions

  if((CURRENT == 3) || ((CURRENT == 0) && encoderType)) {  //A valid tick can occur only at a detent

    if(TOTAL == (ZEERO + THRESH)) {
      currentValue++;
    }

    else if(TOTAL == (ZEERO - THRESH)) {
      currentValue--;
    }
    TOTAL = ZEERO;                      //Always reset TOTAL to 0x80 at detent
  }
}

Not the answer you're looking for, but I'll share what I know on this subject: I did a project using an encoder and an ESP8266 board. I used the popular Encoder library and also had crashes until I set the library's "ENCODER_DO_NOT_USE_INTERRUPTS" configuration option, like so:

#define ENCODER_DO_NOT_USE_INTERRUPTS
#include <Encoder.h>

You can see it demonstrated in the library's example:

Well I have to admit I've never used interrupts on the D1 Mini before, but I haven't seen anything suggesting they can't be used. Until now. And there were no errors or warnings during compiling or flashing. I wonder what the deal is.

Ok, I got it working. The main problem was you have to put the ISR in ram:

ICACHE_RAM_ATTR void Encoder() {
-etc-

That stopped the error messages, but it still didn't work. Then I found that if you want to use pin D2, you have to say "D2", not just "2". Otherwise it thinks you mean GPIO2, which is a different pin. Anyway, this now works on the D1 Mini:

/*
ESP8266
Rotary encoder - Standard lookup table method - both pin-change interrupts enabled.

Interrupts are enabled on both pins.  When either pin triggers an interrupt, the
pins are read, and the change from the previous state is interpreted through a
lookup table.  So all the bouncing on both pins triggers interrupts.

With the appropriate "encoderType" definition, this will work for encoders with
the same number of pulses as detents per revolution (Type 0), as well as for those
with half as many pulses as detents (Type 1).  In either case, the code produces
one tick per detent.  For Type 0, that is only when both switches are open.
For Type 1 encoders, switches can be either both open or both closed at a detent.

The encoder pins are connected to D1 and D2.  The code increments or decrements
the variable "currentValue" when the encoder knob is moved to the next detent,
and the value is sent to the serial monitor whenever it changes.
*/

const int aPIN = D1;                    // encoder pins
const int bPIN = D2;

const byte encoderType = 0;             // encoder with equal # of detents & pulses per rev
//const byte encoderType = 1;             // encoder with  pulses = detents/2. pick one, commment out the other

const int THRESH =(4-(2*encoderType));  // transitions needed to recognize a tick - type 0 = 4, type 1 = 2

const byte ZEERO = 0x80;                // byte data type doesn't do negative

volatile int currentValue = 0;
int oldValue = 0;
byte CURRENT;                           // the current state of the switches
byte INDEX = 15;                        // Index into lookup state table
byte TOTAL = 0;

// Encoder state table - there are 16 possible transitions between interrupts

int ENCTABLE[]  = {0,1,-1,0,-1,0,0,1,1,0,0,-1,0,-1,1,0};

void setup() {

  Serial.begin(9600);

  pinMode(aPIN, INPUT_PULLUP);          // set up encoder pins as INPUT-PULLUP
  pinMode(bPIN, INPUT_PULLUP);

  attachInterrupt(digitalPinToInterrupt(aPIN), Encoder, CHANGE);
  attachInterrupt(digitalPinToInterrupt(bPIN), Encoder, CHANGE);
}

void loop() {

  if(currentValue != oldValue) {        // serial print current value when it changes
    Serial.println(currentValue);
    oldValue = currentValue;
  }
}

ICACHE_RAM_ATTR void Encoder() {        // pin change interrupts service routine. interrupts
                                        //     automatically disabled during execution

  INDEX     = INDEX << 2;               // Shift previous state left 2 bits (0 in)
  if(digitalRead (aPIN)) bitSet(INDEX,0); // If aPIN is high, set INDEX bit 0
  if(digitalRead (bPIN)) bitSet(INDEX,1); // If bPIN is high, set INDEX bit 1
  CURRENT = INDEX & 3;                  // CURRENT is the two low-order bits of INDEX
  INDEX &= 15;                          // Mask out all but prev and current

// INDEX is now a four-bit index into the 16-byte ENCTABLE state table

  TOTAL += ENCTABLE[INDEX];             //Accumulate transitions

  if((CURRENT == 3) || ((CURRENT == 0) && encoderType)) {  //A valid tick can occur only at a detent

    if(TOTAL == (ZEERO + THRESH)) {
      currentValue++;
    }

    else if(TOTAL == (ZEERO - THRESH)) {
      currentValue--;
    }
    TOTAL = ZEERO;                      //Always reset TOTAL to 0x80 at detent
  }
}

I'm glad to see you got it working!

That D2 vs 2 quirk of ESP8266 caused me a good hour of head scratching the first time I played around with a WeMos board. It's even more confusing because some of the ESP8266 boards are like that, but others which I had worked with previously don't have this Dn thing and the numbers marked on the board are the GPIO numbers. It had me thinking the board was incorrectly routed for a while.