Loading ...
Sorry, an error occurred while loading the content.

MITS Basic on Z80

Expand Messages
  • who88777
    The Z80 is claimed to be compatible with the 8080 but anyone who has tried to run MITS Basic on it knows that isn t true. The reason is that the Z-80
    Message 1 of 1 , Jan 8, 2013
    • 0 Attachment
      The Z80 is claimed to be compatible with the 8080 but anyone who has tried to run MITS Basic on it knows that isn't true. The reason is that the Z-80 overloads the parity flag and uses it as an overflow flag for arithmetic instructions. To get the 4K basic as small as it was Bill Gates and Paul Allen used every detail of the 8080 to the point where this minor change stops it from working.

      At this point there appears to only be vague hints about the problem online so I'm posting this here to help anybody else out working on the issue (hopefully Google will pick it up). To get MITS Basic to run on a Z80 without modifying the code you have to trap the 8080 arithmetic instructions and recompute the parity flag.

      Here is my code to do this with the z80ex emulator library:

      bool FArithmeticOp(int op)
      {
      if ((op & 0xF0) == 0x80) //ADDr ADDm ADCr ADCm
      return true;
      if (op == 0xC6) //ADI
      return true;
      if (op == 0xCE) //ACI
      return true;
      if (((op & 0x0F) == 0x09) && ((op & 0xC0) == 0)) //DAD (all)
      return true;
      if ((op & 0xF0) == 0x90) // SUB and SBB
      return true;
      if (op == 0xD6) // SUI
      return true;
      if (op == 0xDE) // SBI
      return true;
      if (op == 0x27) // DAA
      return true;

      if ((op & 0xC0) == 0)
      {
      //Increment group
      if ((op & 0x7) == 0x4) //INR
      return true;
      if (op == 0x3) // INX B
      return true;
      if (op == 0x13) // INX D
      return true;
      if (op == 0x23) // INX H
      return true;
      if (op == 0x33) // INX SP
      return true;
      if ((op & 0x7) == 0x5) // DCR
      return true;
      if (op == 0xB) // DCX B
      return true;
      if (op == 0x1B) // DCX D
      return true;
      if (op == 0x2B) // DCX H
      return true;
      if (op == 0x3B) // DCX SP
      return true;
      }

      return false;
      }

      void Machine::SingleStep()
      {
      int ip = z80ex_get_reg(m_pz80ctx, regPC);
      int lastop = m_mem[ip];

      z80ex_step(m_pz80ctx);

      // 8080 arithmetic HACK
      if (FArithmeticOp(lastop))
      {
      int regAFT = z80ex_get_reg(m_pz80ctx, regAF);
      if (FEvenParity(regAFT >> 8))
      regAFT = regAFT | 0x4;
      else
      regAFT = regAFT & (~0x4);
      z80ex_set_reg(m_pz80ctx, regAF, regAFT);
      }
      }

      I hope this helps somebody in the future.

      -John
    Your message has been successfully submitted and would be delivered to recipients shortly.