How does TWI Slave serve two different ISRs based on only one Interrupt Vector?

I would like to take the help of the following diagram to support the clarity of my query/question:

From Serial Monitor-1, I send character B as a command which in turn is transmitted to the Slave by the Master using the following instructions:

Wire.beginTransmission(slaveAddress);
Wire.write(x); //x = 'B' = 0x42
Wire.endTransmission();

The Slave receives the command (character B) via Wire.onReceive() ISR (interrupt sub routine) which is due to TWI Bus interrupt of interrupt vector 0x0030. The slave saves the meaning of the command, which is this: the Slave will read the input data of Port-B, and the data will be sent to the Master when such request will arrive from the Master. (Similarly, I can have command C for up-transmission of Port-C data, command D for up-transmission of Port-B and Port-C.)

The Master makes the above request by executing the following instruction:
Wire.requestFrom(slaveAddress, 1);

The Slave goes to the Wire.onRequest() ISR due to TWI Bus interrupt (interrupt vector 0x0030); it reads the input data of Port-B and sends them to the Master by executing the Wire.write() instruction.

My query/question is: When there is only one TWI Bus interrupt request due to interrupt vector 0x0030, how does the Slave (ATmega328P of UNO-2) correctly serves two different ISRs -- Wire.onReceive() and Wire.onRequest().

see your self. it is open source. scroll down. the last function is the interrupt handler. after the comment // Slave Receiver.

onReceive and onRequest are called in twi_onSlaveReceive and in twi_onSlaveTransmit()

When there is only one TWI Bus interrupt request due to interrupt vector 0x0030, how does the Slave (ATmega328P of UNO-2) correctly serves two different ISRs -- Wire.onReceive() and Wire.onRequest().

The answer lies in the fact that there is a TWI Status Register.

When an event requiring the attention of the application occurs on the TWI
bus, the TWI Interrupt Flag (TWINT) is asserted. In the next clock cycle, the TWI Status Register
(TWSRn) is updated with a status code identifying the event.

The interrupt ISR reads the status register. If you look in the utility folder in the wire library you will find a twi.c file. Inside you will find the ISR(TWI_vect) which is a large switch case based on the status register. Somewhere buried in there is the different response to Wire.onReceive() and Wire.onRequest().

@Juraj and @cattledog

Your generous responses to my post have indeed encouraged me to delve a little more into the implementation technology of TWI Bus under Wire.h-Wire.cpp-(twi.h-twi.c) Libraries. I have tried to understand experimentally the Library Protocols, particularly the Wire.onReceive() and Wire.onRequest() interrupt sub routines, by bringing in the corresponding Register Level Instructions and the Status Words (SWRD). The studies have appeared meaningful and enhanced my understanding on TWI Bus, which I would like to present here in Q/A format.

Q1: The Master sends to the Slave 2 bytes data (say, 0x23 and 0x45). How does the Slave receive them using interrupt sub routine -- the Wire.onReceive().

A1: The Master executes the following Arduino instructions:
Wire.beginTransmission(slaveAddress);
Wire.write(0x23);
Wire.write(0x45);
Wire.endTransmission();

The above Arduino Level instructions could be broken down into the following Register Level Instructions (approximately and conceptually) in order to understand when the Wire.onReceive() ISR is called upon. The full program codes are given at the end of this Section.

TWCR = 0b10100100; //no SCL is ON (TWCR = TWINT TWEA TWSTA TWSTO TWWC TWEN X TWIE)
while(bitRead(TWCR,7)!= HIGH) //detecting the end of process by finding LH at TWINT-bit
;
lcd.print((TWSR & 0b11111000),HEX); //SWRD = 0x08 indicates -- Master has acquired TWI Bus

Reaction of Slave: none.
//---------------------------------------------------------------------------------------------------------------

TWDR = 0b00001110; //slaveAddres+W-bit = 0b0000111 + 0
TWCR = 0b10000100; //9 SCL is ON
while(bitRead(TWCR,7)!= HIGH)
;
lcd.print((TWSR & 0b11111000),HEX); //SWORD=0x18 -- Slave has recognized its address; creates ACK

Reaction of Slave: Slave is ready to read data from Master, which are coming next. The expected SWRD that has been generated in the TWSR of the Slave is 0x60. The Slave has kept interrupt logic disabled; it will be enabled when needed.
//----------------------------------------------------------------------------------------------------------------

TWDR = 0x23; //sending data byte 0x23 to the Slave
TWCR = 0b10000100; //9 SCL in ON
while(bitRead(TWCR,7)!= HIGH)
;
lcd.print((TWSR & 0b11111000),HEX); //SWRD = 0x28 genertaed in TWSR Register of Master;
//it indicates that the Slave has received data 0x23

Reaction of Slave: It has received data 0x23, and it is saved in a variable x. Slave sends ACK to Master. Expected SWRD 0x80 has been generated in its TWSR Register.
//---------------------------------------------------------------------------------------------------------------

TWDR = 0x45; //2nd data byte 0x45 will be sent to Slave
TWCR = 0b10000100; //9 SCL in ON
while(bitRead(TWCR,7)!= HIGH)
;
lcd.print((TWSR & 0b11111000),HEX); //SWRD = 0x28 genertaed in TWSR Register of Master;
//it indicates that the Slave has received data 0x45

Reaction of Slave: It has received data 0x45, and it is saved in a variable y. Slave sends ACK to Master. Expected SWRD 0x80 has been generated in its TWSR Register.
//---------------------------------------------------------------------------------------------------------------

TWCR = 0b10010100; //no SCL is ON STOP command; the TWI Bus released

Reaction of Slave: Slave recognized STOP command and accordingly generates SWRD 0xA0. Because Slave knows that STOP command is coming, it enables the interrupt logic before starting the polling of TWINT-bit to detect the end of process. (Pls See Slave Codes)

The TWINT-bit of the TWCR Register shortly assumes LH-state; it interrupts the the MCU. The MCU will go to the ISR(TWI_vect)/Wire.onReceive(), and it will read the value of x and y from the FIFO buffer.

//------------------------------------------------------------------------------------------------------------------
Program Codes for Master

#include<LiquidCrystal.h>
LiquidCrystal lcd(A0, A1, A2, A3, 8, 9);

void setup() 
{
  lcd.begin(16, 2);
  lcd.setCursor(0, 0);
  pinMode(13, OUTPUT);
  TWBR = 0x02;
  TWSR = 0x02;

  TWCR = 0b10100100; //no SCL is ON//(TWINT TWEA TWSTA TWSTO TWWC TWEN X TWIE  
while(bitRead(TWCR,7)!= HIGH)
      ;
lcd.print((TWSR & 0b11111000),HEX); //0x08
//--------------------------------------

TWDR = 0b00001110; //slaveAddress = SLA+W-bit = 0b0000111 + 0 
TWCR = 0b10000100; //9 SCL is ON  
while(bitRead(TWCR,7)!= HIGH)
      ;
lcd.print((TWSR & 0b11111000),HEX); //0x18
//------------------------------------------

TWDR = 0x23;
TWCR = 0b10000100; //9 SCL in ON 
while(bitRead(TWCR,7)!= HIGH)
      ;
lcd.print((TWSR & 0b11111000),HEX);  //SWRD = 0x28
//-------------------------------------------------

TWDR = 0x45;
TWCR = 0b10000100; //9 SCL in ON 
while(bitRead(TWCR,7)!= HIGH)
      ;
lcd.print((TWSR & 0b11111000),HEX);  //SWRD = 0x28
//-------------------------------------------------

TWCR = 0b10010100; //no SCL is ON  STOP command



  
} 

void loop() 
{
  digitalWrite(13, !digitalRead(13));
  delay(1000);
}

Program Codes for Slave

#include<LiquidCrystal.h>
LiquidCrystal lcd(A0, A1, A2, A3, 8,9);
byte x, y;

void setup() 
{
  TWBR = 0x02; //TWI BUs speed: 200 kHz
  TWSR = 0x02;
  
  lcd.begin(16, 2);
  lcd.setCursor(0, 0);
  pinMode(13, OUTPUT);
 // lcd.print("OK");

  TWAR = 0b00001110;   //slaveAddress
  TWCR = 0b11000100;   //TWI Interrupt is disabled
 
 while(bitRead(TWCR,7)!= HIGH)
      ;
lcd.print((TWSR & 0b11111000),HEX); //print: SWRD 0x60 (correct)
//--------------------------------------------
 TWCR = 0b11000100;   //TWI Interrupt is disabled
 while(bitRead(TWCR,7)!= HIGH)
      ;
lcd.print((TWSR & 0b11111000),HEX); //print: SWRD 0x80 (correct)
x = TWDR;   //data byte 0x23 read 
lcd.print(x, HEX); //data is shown on LCD
//----------------------------------------------

TWCR = 0b11000100;   //TWI Interrupt is disabled
 while(bitRead(TWCR,7)!= HIGH)
      ;
lcd.print((TWSR & 0b11111000),HEX); //print: SWRD 0x80 (correct)
y = TWDR;   //data byte 0x45 read 
lcd.print(y, HEX); //data is shown on LCD
//----------------------------------------------

TWCR = 0b11000100;   //TWI Interrupt is disabled; TWINT-bit cleared
bitSet(TWCR, 0); //TWI interruot is enabled
bitSet(SREG, 7);  //Global interrupt bit is enabled
 while(bitRead(TWCR,7)!= HIGH)
      ;
//lcd.print((TWSR & 0b11111000),HEX); //print: SWRD 0xA0(correct)
//The MCU is interrupte; it goes to ISR(TW_vect) which is the same as
//Wire.onReceive() ISR of Wire.h Library
}

void loop() 
{
  digitalWrite(13, !digitalRead(13));
  delay(1000);
}

ISR(TWI_vect)
{
  lcd.setCursor(0, 1);
  lcd.print(x, HEX);
  lcd.print(y, HEX);
}