示例#1
0
void cpu_read_6502(uint16_t address, uint16_t length, uint8_t *data)
{
	while(length != 0){
		//phi2 down
/*		uint8_t c = bit_get_negative(CPU_PHI2);
		BUS_CONTROL_OUT = c;*/
		uint8_t c = BUS_CLOSE;
		//down -> up
		direction_write();
		address_set(address);
		BUS_CONTROL_OUT = c;
		clock_wait(1);
		
		//phi2 up
		c |= (1 << CPU_PHI2);
		if((address & 0x8000) != 0){
			c &= bit_get_negative(CPU_ROMCS);
		}
		BUS_CONTROL_OUT = c;
		direction_read();
		clock_wait(1);
		*data = DATABUS_IN;
		data += 1;

		BUS_CONTROL_OUT = c;
		
		//phi2 down, bus close
		BUS_CONTROL_OUT = BUS_CLOSE;
		
		address += 1;
		length--;
	}
	address_set(ADDRESS_CLOSE);
}
示例#2
0
void cpu_write_6502_nowait(uint16_t address, uint16_t length, const uint8_t *data)
{
	while(length != 0){
		uint8_t control;
		address_set(address);
		
		//phi2 down
		control = bit_get_negative(CPU_RW) & bit_get_negative(CPU_PHI2);
		BUS_CONTROL_OUT = control;
		
		//phi2 up
		control |= (1 << CPU_PHI2);
		if((address & 0x8000) != 0){
			control &= bit_get_negative(CPU_ROMCS);
		}
		BUS_CONTROL_OUT = control;
		
		//data set
		DATABUS_OUT = *data;
		data++;
		
		//phi2 down
		control &= bit_get_negative(CPU_PHI2);
		BUS_CONTROL_OUT = control;
		
		//bus close
		BUS_CONTROL_OUT = BUS_CLOSE;
		
		address += 1;
		length--;
	}
	address_set(ADDRESS_CLOSE);
}
示例#3
0
static inline void ppu_write_waveform(uint16_t address, uint8_t data)
{
	address_set(address);//PPU charcter memory /CS open
	BUS_CONTROL_OUT = bit_get_negative(PPU_WR) & bit_get_negative(CPU_PHI2);
	DATABUS_OUT = data;
	BUS_CONTROL_OUT = BUS_CLOSE;
	address_set(0x3fff); ///CS close, use pallete area. When address bus is 0x2000-0x2fff, some cartriges enable tilemap area.
}
示例#4
0
/*******************************************************************************
* Function Name  : dis_baiye
* Description    : display the picture as the type of baiye windows
* author         :zhangxianyuan
* Input          : - file: pointer to the source file name
*                  - line: assert_param error line source number
* Output         : None
* Return         : None
*******************************************************************************/
void dis_baiye(void) 
{	
	int i, j, m, n, x;  
	unsigned int dd;   	  
 //	address_set(0, 0, 239, 319);
//	LCD_Clear(White);
	for(j = 0; j <= 60; j++)
	{	
 		for(m = 0; m < 4 ;m++)
		{
		 	if(m % 2 == 1)
		 	{
			 	x = 1;
		 	}	
			for(n = 0; n< 2; n++)
			{
				address_set(60 * m + j,160 * n + 80 * x,60 * m + j, 160 * n + 80 + 80 * x);
				for(i = 320 * (60 * m + j) + 160 * n + 80 * x; i < 320 *(60 * m + j) + 160 * n + 80 + 80 * x; i++)
			 	{
				 	dd = (0x00 | gImage_111[i * 2 + 1]) << 8;
				  	dd = dd | gImage_111[ i * 2];
				  	LCD_WriteRAM(dd);
			  	}
				    	  
			}
			x = 0;
		 }
    	 Delay(5000);
	}

	for(j = 0;j <= 60; j++)
	{	
		 for(m = 0; m < 4; m++)
		 {
		 	if(m % 2 == 0)
		 	{
			 	x = 1;
		 	}	
			for(n = 0; n < 2; n++)
			{
				address_set(60 * (m + 1) - j, 160 * n + 80 * x, 60 * (m + 1) - j, 160 * n + 80 + 80 * x);
				for(i = 320 * (60 * (m + 1) - j) + 160 * n + 80 * x; i < 320 * (60 * (m + 1) - j) + 160 * n + 80 + 80 * x; i++)
			 	{
				 	dd = (0x00 | gImage_111[i * 2 + 1]) << 8;
				  	dd = dd|gImage_111[i * 2];
				  	LCD_WriteRAM(dd);
			  	}    	  
			}
			x = 0;
		   }
    	   Delay(10000);
	}
}
示例#5
0
void*
fastuidraw::memory::
calloc_implement(size_t nmemb, size_t size, const char *file, int line)
{
  void *return_value;

  if (nmemb == 0 || size == 0)
    {
      return nullptr;
    }

  return_value = std::calloc(nmemb, size);

  #ifdef FASTUIDRAW_DEBUG
    {
      if (!return_value)
        {
          bad_malloc_message(size * nmemb, file, line);
        }
      else
        {
          address_set().track(return_value, file, line);
        }
    }
  #else
    {
      FASTUIDRAWunused(file);
      FASTUIDRAWunused(line);
    }
  #endif

  return return_value;
}
示例#6
0
//////////////////////////////////////////////////////
// fastuidraw::memory methods
void
fastuidraw::memory::
check_object_exists(const void *ptr, const char *file, int line)
{
  #ifdef FASTUIDRAW_DEBUG
    {
      if (!ptr)
        {
          return;
        }

      if (!address_set().exists(ptr))
        {
          std::cerr << "Untracked object from [" << file << ", "
                    << line << "] @" << ptr << "\n" << std::flush;
        }
    }
  #else
    {
      FASTUIDRAWunused(file);
      FASTUIDRAWunused(line);
      FASTUIDRAWunused(ptr);
    }
  #endif
}
示例#7
0
void mld_group_interface::handle_last_listener_query() {
	if (g_last_listener_query_count
		== g_intf->conf()->last_listener_query_count()) {
		/* If we reach here, no one reported */

		g_last_listener_timer.stop();

		delete_sources(g_exclude_set);

		g_include_set.clear();
		g_request_set.clear();
		g_exclude_set.clear();

		g_filter_mode = include;

		dump_filter();

		owner()->trigger_mode_event(this, all_sources, address_set());

		owner()->someone_lost_interest();
	} else {
		/* Send Q(MA) */
		send_mld_query(true);

		g_last_listener_query_count ++;
	}
}
示例#8
0
/*
/WE controlled write operation has busconflict
PHI2  |-__________-
R/W   |----___-----
/ROMCS|--_______---
A0-A14|-<vaild address>-
D0-D7 |--oo<i>**---
o is dataout, i is datain, * is bus-confilict

/CS controlled write operation is clean write cycle for flash memory
PHI2  |-__________-
R/W   |--_______---
/ROMCS|----___-----
A0-A14|-<vaild address>-
D0-D7 |----<iii>---
*/
static inline void cpu_write_flash_waveform(uint16_t address, uint8_t data)
{
	uint8_t control = bit_get_negative(CPU_PHI2);
	address_set(address);
	if(0){ //R/W = /WE controlled write operation
		if((address & 0x8000) != 0){
			control &= bit_get_negative(CPU_ROMCS);
			BUS_CONTROL_OUT = control;
		}
		control &= bit_get_negative(CPU_RW);
		BUS_CONTROL_OUT = control;
		DATABUS_OUT = data;
		control |= 1 << CPU_RW; //R/W close
		BUS_CONTROL_OUT = control;
	}else{ ///ROMCS = /CS controlled write operation
		control &= bit_get_negative(CPU_RW);
		BUS_CONTROL_OUT = control;
		if((address & 0x8000) != 0){
			control &= bit_get_negative(CPU_ROMCS);
			BUS_CONTROL_OUT = control;
		}
		DATABUS_OUT = data;
		control |= 1 << CPU_ROMCS;
		BUS_CONTROL_OUT = control;
	}
	BUS_CONTROL_OUT = BUS_CLOSE;
}
示例#9
0
文件: group.cpp 项目: NeoRaider/mrd6
void group_interface::shutdown() {
	g_filter_mode = include;
	g_include_set.clear();
	g_exclude_set.clear();

	owner()->trigger_mode_event(this, all_sources, address_set());
}
示例#10
0
void*
fastuidraw::memory::
realloc_implement(void *ptr, size_t size, const char *file, int line)
{
  void *return_value;

  if (!ptr)
    {
      return malloc_implement(size, file, line);
    }

  if (size == 0)
    {
      free_implement(ptr, file, line);
      return nullptr;
    }

  #ifdef FASTUIDRAW_DEBUG
    {
      if (!address_set().present(ptr))
        {
          std::cerr << "Realloc from [" << file << ", "  << line
                    << "] of untracked @" << ptr << "\n"
                    << std::flush;
        }
    }
  #else
    {
      FASTUIDRAWunused(file);
      FASTUIDRAWunused(line);
    }
  #endif

  return_value = std::realloc(ptr, size);

  #ifdef FASTUIDRAW_DEBUG
    {
      if (return_value != ptr)
        {
          address_set().untrack(ptr, file, line);
          address_set().track(return_value, file, line);
        }
    }
  #endif

  return return_value;
}
示例#11
0
void bus_init(void)
{
	DATABUS_DIR = DATABUS_DIR_OUT;
	BUS_CONTROL_DIR = (1 << CPU_PHI2) | (1 << CPU_ROMCS) | (1 << CPU_RW) | (1 << PPU_RD) | (1 << PPU_WR);
	BUS_CONTROL_OUT = BUS_CLOSE;
	USB_MISC_DIR = (1 << ADDRESS_HIGH_LATCH) | (1 << ADDRESS_LOW_LATCH);
	USB_MISC_PULLUP = (1 << VRAM_A10)| (1 << VRAM_CS);
	address_set(ADDRESS_CLOSE);
}
示例#12
0
void bus_init(void)
{
	ADDRESSBUS_A0_A7_DIR = 0xff;
	DATABUS_DIR = DATABUS_DIR_OUT;
	BUS_CONTROL_DIR = bit_get_negative(VRAM_CS); //VRAM_CS is input port
	BUS_CONTROL_OUT = BUS_CLOSE;
	USB_MISC_DIR = (0b1100 << 4) | 0b0011; //empty pin use OUT
	USB_MISC_PULLUP = (1 << CPU_IRQ) | (1 << VRAM_A10);
	address_set(ADDRESS_CLOSE);
}
示例#13
0
void cpu_write_flash(uint16_t address, uint16_t length, const uint8_t *data)
{
	direction_write();
	while(length != 0){
		cpu_write_flash_waveform(address, *data);
		data++;
		address += 1;
		length--;
	}
	address_set(ADDRESS_CLOSE);
}
示例#14
0
void cpu_write_flash_order(const struct flash_order *t)
{
	int length = FLASH_PROGRAM_ORDER;
	direction_write();
	while(length != 0){
		cpu_write_flash_waveform(t->address, t->data);
		t++;
		length--;
	}
	address_set(ADDRESS_CLOSE);
}
示例#15
0
/*******************************************************************************
* Function Name  : show_picture
* Description    : show one picture
* author         :wangxiaotao
* Input          : - file: pointer to the source file name
*                  - line: assert_param error line source number
* Output         : None
* Return         : None
*******************************************************************************/
void show_picture(const unsigned char *p)
{
	int i;
	unsigned int dd;
	address_set(0,0,239,319);
    for(i=0;i<320*240;i++)
	 {
		  dd=(0x00 | p[i * 2 + 1])<<8;
		  dd=dd | p[i * 2];
		  LCD_WriteRAM(dd);
	 }
}
示例#16
0
uint8_t vram_connection_get(void)
{
	uint8_t ret;
	uint16_t address = 0x2000;
	direction_write();
	address_set(address);
	ret = bit_get(USB_MISC_IN, VRAM_A10);
	address += 1 << 10;

	address_set(address);
	ret |= bit_get(USB_MISC_IN, VRAM_A10) << 1;
	address += 1 << 10;
	
	address_set(address);
	ret |= bit_get(USB_MISC_IN, VRAM_A10) << 2;
	address += 1 << 10;

	address_set(address);
	ret |= bit_get(USB_MISC_IN, VRAM_A10) << 3;
	address += 1 << 10;
	
	return ret;
}
示例#17
0
/*******************************************************************************
* Function Name  : dis_zhongkai
* Description    : dis_zhongkai
* author         :zhangxianyuan
* Input          : - file: pointer to the source file name
*                  - line: assert_param error line source number
* Output         : None
* Return         : None
*******************************************************************************/
void dis_zhongkai(void)
{
	int i,j;
	unsigned int dd;
	for(j = 0; j < 25; j++)
	{
		address_set(120 - 5 * j, 0, 120 + 5 * j, 319); 
	    for(i = (120 - 5 * j) * 320; i <= 320 * (120 + (j * 5)); i++)
		{
			 dd=(0x00 | gImage_1[i * 2 + 1])<<8;
			 dd=dd | gImage_1[i * 2];
			 LCD_WriteRAM(dd);
		 }
	}
}
/*******************************************************************************
* Author		 : 国文刚
* Date           : 07/01/2011
* Function Name  : DisplayDownUp
* Description    : void DisplayDownUp(void).
* Input          : - girl_1: The array data of picture named home_picture.
* Output         : None
* Return         : None
*******************************************************************************/
void DisplayDownUp(void)
{
	unsigned int dd,i;
	int k;
	for(i = 24; i>0; i--)
    {	
		address_set((i-1)*10, 0, 239, 319);   //设置坐标   
		for(k = 0; k < (25 - i)*3200; k++)		 
		{
			dd = (0x00|girl_1[k*2 + 1])<<8;
	        dd = dd|girl_1[k*2];  	
	        LCD_WriteRAM(dd);
	   	}
	}
}
示例#19
0
void mld_group_interface::handle_filter_timer() {
	delete_sources(g_exclude_set);

	g_include_set = g_request_set;
	g_request_set.clear();
	g_exclude_set.clear();

	g_filter_mode = include;

	dump_filter();

	owner()->trigger_mode_event(this, all_sources, address_set());

	if (g_include_set.empty())
		owner()->someone_lost_interest();
}
示例#20
0
void ppu_read(uint16_t address, uint16_t length, uint8_t *data)
{
	//BUS_CONTROL_OUT = BUS_CLOSE;
	while(length != 0){
		direction_write();
		address_set(address);
		BUS_CONTROL_OUT = bit_get_negative(PPU_RD) & bit_get_negative(CPU_PHI2);
		direction_read();
		*data = DATABUS_IN;
		data += 1;
		BUS_CONTROL_OUT = BUS_CLOSE;
		address += 1;
		length--;
	}
	direction_write();
}
示例#21
0
void mld_interface::handle_mldv1_membership_reduction(const in6_addr &src,
						      mldv1 *mldhdr) {
	m_stats.counter(ReductionCount, RX)++;
	mld->stats().counter(ReductionCount, RX)++;

	if (!IN6_IS_ADDR_MULTICAST(&mldhdr->mcaddr)) {
		m_stats.counter(ReductionCount, Bad)++;
		mld->stats().counter(ReductionCount, Bad)++;
		return;
	}

	if (IN6_IS_ADDR_MC_NODELOCAL(&mldhdr->mcaddr)
	    || IN6_IS_ADDR_MC_LINKLOCAL(&mldhdr->mcaddr))
		return;

	handle_mode_change_for_group(1, src, mldhdr->mcaddr,
				     MLD_SSM_CHANGE_TO_INCLUDE, address_set());
}
示例#22
0
enum compare_status ppu_compare(uint16_t address, uint16_t length, const uint8_t *data)
{
	while(length != 0){
		direction_write();
		address_set(address);
		BUS_CONTROL_OUT = bit_get_negative(PPU_RD) & bit_get_negative(CPU_PHI2);;
		direction_read();
		if(DATABUS_IN != *data){
			BUS_CONTROL_OUT = BUS_CLOSE;
			direction_write();
			return NG;
		}
		data += 1;
		BUS_CONTROL_OUT = BUS_CLOSE;
		address += 1;
		length--;
	}
	direction_write();
	return OK;
}
示例#23
0
void
fastuidraw::memory::
free_implement(void *ptr, const char *file, int line)
{
  #ifdef FASTUIDRAW_DEBUG
    {
      if (ptr)
        {
          address_set().untrack(ptr, file, line);
        }
    }
  #else
    {
      FASTUIDRAWunused(file);
      FASTUIDRAWunused(line);
    }
  #endif

  std::free(ptr);
}
void DisplayCorner(void)
{
	int i, l, k;
	int dd;
	for(i=0 ; i<10; i++)				  //横纵标10等分
	{
	 	address_set((9-i)*24,(9-i)*32,239,319);	  //设置每次写入坐标
		for(k = 0; k < (i+1)*24; k++ )		   //刷新次数
		{
			for(l = k*320; l < k*320+(i+1)*32; l++ )   //纵向扫描次数
			{
				dd=(0x00|girl_2[l*2+1])<<8;
	            dd=dd|girl_2[l*2];  	
	            LCD_WriteRAM(dd);	
			}
		}
		Delay(0xffff);	   //延时
		Delay(0xffff);	 
	 }		 
}
示例#25
0
//mmc5 ROM area need that phi2 is high
void cpu_read(uint16_t address, uint16_t length, uint8_t *data)
{
	BUS_CONTROL_OUT = BUS_CLOSE;
	while(length != 0){
		uint8_t c = BUS_CLOSE;
		direction_write();
		address_set(address);
		if((address & 0x8000) != 0){
			c &= bit_get_negative(CPU_ROMCS);
//			BUS_CONTROL_OUT = c;
//			BUS_CONTROL_OUT = bit_get_negative(CPU_ROMCS);
		}
		c |= 1 << CPU_PHI2;
		BUS_CONTROL_OUT = c;
		direction_read();
		*data = DATABUS_IN;
		data += 1;
		BUS_CONTROL_OUT = BUS_CLOSE;
		address += 1;
		length--;
	}
	direction_write();
}
示例#26
0
/*******************************************************************************
* Function Name  : dis_juanxing
* Description    : display the picture as the type of juanxing
* author         :hulongchuan
* Input          : - file: pointer to the source file name
*                  - line: assert_param error line source number
* Output         : None
* Return         : None
*******************************************************************************/
void dis_juanxing(void)
{
	u16 i,j;
  	address_set(0, 0, 47, 319);
  	for(i = 0; i < 320; i++)
    	for(j = 0; j < 240; j++)
	    { 
	      	if(i < 48)
		   		LCD_WriteRAM(0x0000);
	    }
	address_set(0, 0, 239, 63);
  	for(i = 0; i < 320; i++)
    	for(j = 0; j < 240; j++)
	    { 
	      	if(i < 64)
		   		LCD_WriteRAM(0x0000);
	    }
	address_set(191, 63, 240, 320);
 	for(i = 0; i < 320; i++)
	    for(j = 0;j < 240; j++)
	    { 
	      	if(i < 60)
		   		LCD_WriteRAM(0x0000);
	    }
		address_set(0, 255, 191, 319);
  	for(i = 0; i < 320; i++)
	    for(j = 0; j < 240; j++)
	    { 
	      	if(i < 64)
		   		LCD_WriteRAM(0x0000);
	    }
	address_set(0, 63, 95, 255);
  	for(i = 0; i < 320; i++)
	    for(j = 0; j < 240; j++)
	    { 
	      	if(i < 95)
		   		LCD_WriteRAM(0x0000);
	    }
	address_set(95, 63, 191, 127);
  	for(i = 0; i < 320; i++)
	    for(j = 0; j < 240; j++)
	    { 
	      	if(i < 64)
		   		LCD_WriteRAM(0x0000);
	    }
	address_set(143, 127, 191, 255);
  	for(i = 0; i < 320; i++)
	    for(j = 0; j < 240; j++)
	    { 
	      	if(i < 48)
		   		LCD_WriteRAM(0x0000);
	    }
	address_set(95, 191, 143, 255);
	for(i = 0;i < 320; i++)
	    for(j = 0; j < 240; j++)
	    { 
	      	if(i < 64)
		   		LCD_WriteRAM(0x0000);
	    }
   	address_set(95, 127, 143, 191);
  	for(i = 0; i < 320; i++)
	    for(j = 0; j < 240; j++)
	    { 
	      	if(i < 48)
		   	 	LCD_WriteRAM(0x0000);
	    }
}
void ShowSpecial2(void)
{
	unsigned int  dd,i,m;
	int k ,l;
	u16 fill3;
//	u16 fill1,fill2	
//	unsigned int color[] = {White,Black,Grey,Blue,Blue2,Red,Magenta,Green,Cyan,Yellow };
	int color[10] = {0xFFFF,0x0000,0xF7DE,0x001F,0x051F,0xF800,0xF81F,0x07E0,0x7FFF,0xFFE0};
	
	address_set(0,0,239,319);
	for(i = 0; i < 76800; i++)
    {
		dd=(0x00|girl_1[i*2 + 1])<<8;
		dd=dd|girl_1[i*2];  	
	    LCD_WriteRAM(dd);
	}

	   for(k = 1; k < 7; k++)
	   {
		 for(i = 1; i < 120 ; i++)
		 {
//		 	if(i > 0 && i <= 10)  {fill1 = White; fill2 = Black;}
//			if(i > 10 && i <= 40) {fill1 = Black; fill2 = White;}
//			if(i > 40 && i <= 50) {fill1 = White; fill2 = Black;}
//			if(i > 50 && i <= 80) {fill1 = Black; fill2 = White;}
//			if(i > 80 && i <= 90) {fill1 = White; fill2 = Black;}
//			if(i > 90 && i <= 120){fill1 = Black; fill2 = White;}

		 	if(i == 1)  {fill3 = rand()%10;}
			if(i == 11) {fill3 = rand()%10;}
			if(i == 41) {fill3 = rand()%10;}
			if(i ==51) {fill3 = rand()%10;}
			if(i == 81) {fill3 = rand()%10;}
			if(i == 91){fill3 = rand()%10;}
//			if(k & 1 == 1)  
//				fill3 = fill1;
//			else  
//				fill3 = fill2;
			LCD_DrawCircle1(120, 160, i, color[fill3]);
		 }
	}
		 
	 for(l = 1; l <= 16; l++)
	 {
	// 	for(i=0; i < 20; i++)
	//	{
			for(k = 1; k <= 12; k++)
			{
				if((k&1) == 0)
				{
					address_set((k-1)*20, 0, k*20, l*20);
		//			fill1 = Black ;
		//			fill1 = color[rand()%10];
		//			fill2 = Green ;
		//			fill2 = color[rand()%10];
				}
				if((k&1) == 1)
				{											 
					address_set((k-1)*20, (320-l*20), k*20, 320);
		//			fill1 = color[rand()%10];
		//			fill2 = color[rand()%10];
				}
				fill3 = color[rand()%10];
				for(m = 0; m < 20*l*20; m++)  
				{
			//		if((l&1) == 1)
			//		{
			//			fill3 = fill1;
			//		}
			//		if((l&1) == 0)
			//		{
			//			fill3 = fill2;
			//		}					
					LCD_WriteRAM(fill3);	   
				}
			}
		//}
	 }
	for(i = 24; i > 0; i--)
    {	
		address_set((i-1)*10, 0, 239, 319);   //设置坐标   
		for(k=0; k < (25-i)*3200; k++)		 
		{
			dd=(0x00|girl_1[k*2 + 1])<<8;
	        dd=dd|girl_1[k*2];  	
	        LCD_WriteRAM(dd);
	   	}
	}
}
示例#28
0
void mld_group_interface::refresh(const inet6_addr &src, int mode,
				  const address_set &sources) {
	if (g_last_listener_timer.is_running()
		&& !((mode == MLD_SSM_CHANGE_TO_INCLUDE
		    || mode == MLD_SSM_MODE_INCLUDE) && sources.empty())) {
		/* Cancel fast-leave */
		g_last_listener_timer.stop();
	}

	g_last_reporter = src;

	if (should_log(MESSAGE_SIG)) {
		log().xprintf("Refresh triggered by %{Addr} with mode"
			      " %s and sources %{addrset}.\n", src,
			      _mode_name(mode), sources);
	}

	address_set diff;

	switch (g_filter_mode) {
	case include:
		switch (mode) {
		case MLD_SSM_CHANGE_TO_INCLUDE:
			/* Router State: INCLUDE(A)
			 * Report Received: TO_IN(B)
			 * New Router State: INCLUDE(A+B)
			 * Actions: (B)=MALI, Send Q(MA,A-B) */

			/* Send Q(MA,A-B) */
			send_mld_query(false, g_include_set - sources);

			/* the rest is processed below */

		case MLD_SSM_ALLOW_SOURCES:
		case MLD_SSM_MODE_INCLUDE:
			/* Router State: INCLUDE(A)
			 * Report Received: ALLOW(B), INCLUDE(B)
			 * New Router State: INCLUDE(A+B)
			 * Actions: (B)=MALI */

			/* A = A+B */
			g_include_set.union_with(sources, diff);
			/* (B)=MALI */
			update_sources_timer(sources);

			if (!diff.empty()) {
				dump_filter();
				owner()->trigger_mode_event(this, added_sources, diff);
			}
			break;

		case MLD_SSM_CHANGE_TO_EXCLUDE:
			/* Router State: INCLUDE(A)
			 * Report Received: TO_EX(B)
			 * New Router State: EXCLUDE(A*B,B-A)
			 * Actions: (B-A)=0, Delete (A-B), Send Q(MA,A*B), Filter Timer=MALI */

			/* Send Q(MA,A*B) */
			send_mld_query(false, g_include_set * sources);

			/* the rest is processed below */

		case MLD_SSM_MODE_EXCLUDE:
			/* Router State: INCLUDE(A)
			 * Report Received: EXCLUDE(B)
			 * New Router State: EXCLUDE(A*B,B-A)
			 * Actions: (B-A)=0, Delete (A-B), Filter Timer=MALI */

			g_filter_mode = exclude;

			/* X = A*B */
			g_request_set = g_include_set * sources;
			/* Y = B-A */
			g_exclude_set = sources - g_include_set;

			/* Delete (A-B) */
			delete_sources(g_include_set - sources);

			/* Filter Timer=MALI */
			restart_filter_timer();

			dump_filter();

			owner()->trigger_mode_event(this, all_sources, address_set());
			break;

		case MLD_SSM_BLOCK_SOURCES:
			/* Router State: INCLUDE(A)
			 * Report Received: BLOCK(B)
			 * New Router State: INCLUDE(A)
			 * Actions: Send Q(MA,A*B) */

			/* Fast leave */
			update_sources_timer(sources, g_intf->conf()->last_listener_query_interval() + 500);
			send_mld_query(false, sources);

			/* Send Q(MA,A*B) */
			send_mld_query(false, g_include_set * sources);
			break;
		}
		break;
	case exclude:
		switch (mode) {
		case MLD_SSM_CHANGE_TO_INCLUDE:
			/* Router State: EXCLUDE(X,Y)
			 * Report Received: TO_IN(A)
			 * New Router State: EXCLUDE(X+A,Y-A)
			 * Actions: (A)=MALI, Send Q(MA,X-A), Send Q(MA) */

			/* Send Q(MA,X-A) */
			send_mld_query(false, g_request_set - sources);
			/* Send Q(MA) */
			send_mld_query(true);

			start_fast_leave();

		case MLD_SSM_MODE_INCLUDE:
			/* Router State: EXCLUDE(X,Y)
			 * Report Received: INCLUDE(A)
			 * New Router State: EXCLUDE(X+A,Y-A)
			 * Actions: (A)=MALI */

			/* X = X+A */
			g_request_set.union_with(sources);
			/* Y = Y-A */
			g_exclude_set.diff_with(sources, diff);

			/* (A)=MALI */
			update_sources_timer(sources);

			if (!diff.empty()) {
				dump_filter();
				owner()->trigger_mode_event(this, removed_sources, diff);
			}

			break;

		case MLD_SSM_CHANGE_TO_EXCLUDE:
			/* Router State: EXCLUDE(X,Y)
			 * Report Received: TO_EX(A)
			 * New Router State: EXCLUDE(A-Y,Y*A)
			 * Actions: (A-X-Y)= Filter Timer, Delete (X-A), Delete (Y-A)
			 *	Send Q(MA,A-Y), Filter Timer=MALI */

			/* Send Q(MA,A-Y) */
			send_mld_query(false, sources - g_exclude_set);

		case MLD_SSM_MODE_EXCLUDE:
			/* Router State: EXCLUDE(X,Y)
			 * Report Received: EXCLUDE(A)
			 * New Router State: EXCLUDE(A-Y,Y*A)
			 * Actions: (A-X-Y)=Filter Timer, Delete (X-A), Delete (Y-A)
			 *	Filter Timer=MALI */

			/* (A-X-Y)=Filter Timer */
			update_sources_timer(sources - g_request_set - g_exclude_set,
						g_filter_timer.time_left());

			/* Delete (X-A) */
			delete_sources(g_request_set - sources);
			/* Delete (Y-A) */
			delete_sources(g_exclude_set - sources);

			/* X = A-Y */
			g_request_set = sources - g_exclude_set;
			/* Y = Y*A */
			g_exclude_set.intersect_with(sources);

			/* Filter Timer=MALI */
			restart_filter_timer();
			break;

		case MLD_SSM_ALLOW_SOURCES:
			/* Router State: EXCLUDE(X,Y)
			 * Report Received: ALLOW(A)
			 * New Router State: EXCLUDE(X+A,Y-A)
			 * Actions: (A)=MALI */

			/* X = X+A */
			g_request_set.union_with(sources);
			/* Y = Y-A */
			g_exclude_set.diff_with(sources, diff);

			/* (A)=MALI */
			update_sources_timer(sources);

			if (!diff.empty()) {
				dump_filter();
				owner()->trigger_mode_event(this, added_sources, diff);
			}
			break;

		case MLD_SSM_BLOCK_SOURCES:
			/* Router State: EXCLUDE(X,Y)
			 * Report Received: BLOCK(A)
			 * New Router State: EXCLUDE(X+(A-Y),Y)
			 * Actions: (A-X-Y)=Filter Timer, Send Q(MA,A-Y) */

			/* (A-X-Y)=Filter Timer */
			update_sources_timer(sources - g_request_set - g_exclude_set,
						g_filter_timer.time_left());

			/* Send Q(MA,A-Y) */
			send_mld_query(false, sources - g_exclude_set);

			/* X = X+(A-Y) */
			g_request_set.union_with(sources - g_exclude_set);

			break;
		}
		break;
	}
}