Quote
I'd wager if I had an up-to-date copy of your source tree, I could just use MESS's DMG core right away.

You always do, you have WIP access on my forum :P
And the latest supergameboy is up on my page: http://byuu.org/bsnes/

Here's the fixed joyp_write() function, which is the only difference from what is already available:
Code
void SuperGameBoy::joyp_write(bool p15, bool p14) {
  //===============
  //joypad handling
  //===============

  if(p15 == 1 && p14 == 1) {
    if(joyp15lock == 0 && joyp14lock == 0) {
      joyp15lock = 1;
      joyp14lock = 1;
      joyp_id = (joyp_id + 1) & 3;
    }
  }

  if(p15 == 0 && p14 == 1) joyp15lock = 0;
  if(p15 == 1 && p14 == 0) joyp14lock = 0;

  //===============
  //packet handling
  //===============

  if(p15 == 0 && p14 == 0) {
    //pulse
    pulselock = false;
    packetoffset = 0;
    bitoffset = 0;
    strobelock = true;
    packetlock = false;
    return;
  }

  if(pulselock) return;

  if(p15 == 1 && p14 == 1) {
    strobelock = false;
    return;
  }

  if(strobelock && (p15 + p14 != 0)) {
    //this is a malformed packet
    packetlock = false;
    pulselock = true;
    bitoffset = 0;
    packetoffset = 0;
  }

  if(strobelock) return;

  //p15:1, p14:0 = 0
  //p15:0, p14:1 = 1
  bool bit = (p15 == 0);
  strobelock = true;

  if(packetlock) {
    if(p15 == 1 && p14 == 0) {
      if((joyp_packet[0] >> 3) == 0x11) {
        mmio.mlt_req = joyp_packet[1] & 3;
        if(mmio.mlt_req == 2) mmio.mlt_req = 3;
      }

      if(packetsize < 64) packet[packetsize++] = joyp_packet;
      packetlock = false;
      pulselock = true;
    }
    return;
  }

  bitdata = (bit << 7) | (bitdata >> 1);
  if(++bitoffset < 8) return;

  bitoffset = 0;
  joyp_packet[packetoffset] = bitdata;
  if(++packetoffset < 16) return;
  packetlock = true;
}

It rejects invalid packets, which seems to work great for both Dracula and Zelda DX; without breaking any other games that I know of.

Quote
Could it be that it simply halts the cpu in such a case?

I suppose that is technically possible. I don't see a command to restart the SGB after packets are transmitted, and if we restarted after a $700f read, it'd still probably be too late to change $6003. Plus if the SGB got stopped in the middle of gameplay while sending packets, the audio would most likely stall out for a couple MS, which would cause sharp popping. Thus, it probably doesn't halt.