石原 博の覚書

電子工作に関する日々の覚書を記載します

Z80-MBC2のIOについて

2021-08-09 16:54:33 | 日記

ブートについて調べたのに引き続き、入出力部分を簡単に整理してみた。(S220618_IOS-LITE-Z80-MBC2.ino)

Z80のINあるいはOUT命令では、メモリ空間とは別のIO空間に対してアクセスする。この時MREQではなくIOREQが有効になる。
そこでIOREQでRSラッチを起動し、WAITをかける。CPUは出力あるいは入力状態で停止するので、その状態のデータバスを読み取る。解除はWAIT_RESでRSラッチを解除する。
(RSラッチは初期状態が不明なため、AVRは初期処理でWAIT_RESをLに、PG LOAD前にはHにしている)

 

気をつけるところは、WAIT解除の部分。以下のようにBUSREQを有効にしてからWAITを解除しその後BUSREQを解除している。Twステートを抜けた後T4ステートになる関係か?
INTERRUPTは現状では使っていないようだ。


WRITE
      // Control bus sequence to exit from a wait state (M I/O write cycle)
      digitalWrite(BUSREQ_, LOW);                 // Request for a DMA
      digitalWrite(WAIT_RES_, LOW);               // Reset WAIT FF exiting from WAIT state
      digitalWrite(WAIT_RES_, HIGH);              // Now Z80 is in DMA, so it's safe set WAIT_RES_ HIGH again
      digitalWrite(BUSREQ_, HIGH);                // Resume Z80 from DMA

READ
        // Control bus sequence to exit from a wait state (M I/O read cycle)
        digitalWrite(BUSREQ_, LOW);               // Request for a DMA
        digitalWrite(WAIT_RES_, LOW);             // Now is safe reset WAIT FF (exiting from WAIT state)
        delayMicroseconds(2);                     // Wait 2us just to be sure that Z80 read the data and go HiZ
        DDRA = 0x00;                              // Configure Z80 data bus D0-D7 (PA0-PA7) as input with pull-up
        PORTA = 0xFF;
        digitalWrite(WAIT_RES_, HIGH);            // Now Z80 is in DMA (HiZ), so it's safe set WAIT_RES_ HIGH again
        digitalWrite(BUSREQ_, HIGH);              // Resume Z80 from DMA

INTERRUPT
        // Control bus sequence to exit from a wait state (M interrupt cycle)
        digitalWrite(BUSREQ_, LOW);               // Request for a DMA
        digitalWrite(WAIT_RES_, LOW);             // Reset WAIT FF exiting from WAIT state
        digitalWrite(WAIT_RES_, HIGH);            // Now Z80 is in DMA, so it's safe set WAIT_RES_ HIGH again
        digitalWrite(BUSREQ_, HIGH);              // Resume Z80 from DMA


void serialEvent()
// Set INT_ to ACTIVE if there are received chars from serial to read and if the interrupt generation is enabled
{
  if ((Serial.available()) && Z80IntEnFlag) digitalWrite(INT_, LOW);
}

void printBinaryByte(byte value)
{
  for (byte mask = 0x80; mask; mask >>= 1)
  {
    Serial.print((mask & value) ? '1' : '0');
  }
}