summaryrefslogblamecommitdiffstatshomepage
path: root/src/mess/machine/apple2gs.c
blob: ab7226879bda78297df0b7eeda4ccfa920424cc2 (plain) (tree)




























                                                                      
                                   








                                    
                                       











































































                                                                                                  



                              
                             
                             





                              
 


                             




                                                                             
                                    
 



                                   


                                                                       
 
                            

                                    


                                                                  
 
                                                          




                                                                                 
                                                                              



                                                                        
                                                                        
                                                 

                                                                                                  


                                                    
                                                                                              



                                                      
                                                                      





                                                      

                                                                          
                            

                                                                          


                                     

                                                                   


                                            
                                             








                                                                    
                                                      


                                    
                                                
                         
                                                                                     


                            

                                                                                      
                         
                                                      


                              
                                              







                                                                             
                                                              


                        








                                                                       



                    
                                                      
 
                                                
         
                            

                                                                                                 

                                                                                                      




         
                                                         
 
                                      



                                                                                                      

                                                                                                      


         
                                                   


                  
                                          


            
                                             




                     
                                                          
 
                                                    
         
                                 
                                                 




                              
                                                            
 
                                                    
         
                                  
                                                    








                                                                             
                  
                                                     
 

                                                 





                            
                                                                 
 

                                                 



 
                                             
 
                          



 
                                                                 





                            
                                                                         
 

                                                            
 


                                          



 
                                                 
 
                                 



 
                                                            



                   
                                


 
                                     




                       
                                    
                    
                                                                                  
 
                             
         
                                     

                              
                                                       

                              
                                           
                                                                          

                              
                                             
                                                                           

                              
                                            
                                                                                                               

                              
                                             

                                                                                                               

                              
                                              


                                                         

                              
                                             

                                                                                         





                                    
                                             
                                                  

                              
                                                         
                                                        

                              
                                                        
                                                        

                              

                                                      






                                                           

                                                             

                         
                                                               



                              

                              

                        
                                                                                        

                              
                               


 
















                                                                            
                                                                 









                                                                        
                                                  
 


                                                                     
                           

                                   


                                                 
 
                                               

                                    

                                                       


                                                                
                                                                       
                                                                 

                                              

                                                             
                                                                 

                                              
                                                            
                                                                 

                                              
                                                             

                                                                                                                                                                  
                                            
                                                                                                        

                                              

                                                              
                                                                 



                                                     
                                                                 

                                              
                                                             
                                                                 

                                              
                                                                         

                                                                                       

                                              
                                                                        

                                                                                       

                                              

                                                                      
                                                                 

                                              



                                                                      







                                                                           
                                                                 

                                              

                                              

                                        
                                                                                               



                                              
                                                     
                         
                                                                 
                                            
                                                                                                                                 



                                        
                                                                                      
                                             
                                                                        


                                         
                                                    



                                     

                                                                                               

 







                                                             
                                                   
 

                                      



 
                                          
 



                            
                                                           
         
                                                                     
                 



                                                           


                    


                                               












                                                            
                                                       










                            
                                      
 


                                       
                                            
         

                                                   
 
                                                                             
                 








                                                                            


                 
      

 
                                                     
 
                              
                                                
         

                                                    


                                
                                                
         

                                                      

         

                                                                 


 
                                                             
 

                     

                                                           

                                                                                                                               
                                                                                                   


                          
                                                                     



                                                                                              
                                         

                                                                                    
                                            
                         
                                                 
                                                                   






                                         
                                                            
                 
                                          
                                                        





                                    
                                  
                                  
                      

                                                     
                                                                
                 
                                                      
                                             
                                                                                                   


                 
                                                                                                








                                                                             
                                       
 



                       
                                  
                                            
                              
                                    
                                                  
 
                                                                     
                         

                                                                            


                            
                                                                                           

                         
                                                                      
                         
                                                

                              
                                 
                                                   
                              
                                 
                                                          







                              
                                        
 

                       
                                  

                                                                                                      
                         
                                                      

                              
                                     
                                                                     
                         

                                                                            


                            
                                                                            

                         
                                                                      
                         
                                                

                              
                                 

                                                

                                 

                                                 










                                                                                          
                                       








                                                               
                                                














                                                       

                       
 



                                   
 
                       
 

                      








                                                           
 
                                                 
                                                                                                            

                              
                                                


                                                              
                                               


                                          
                                                  
                                         

                                                             
                                                      
                              

                              
                                                  
                                         

                                                             



                                                                 
                                                           


                                                    
                                                        


                                                    
                                                          


                                                    
                                                                         


                                                       
                                                             





















                                                                                    

                              
                                                
                                         

                                                           
                                                    
                              

                              
                                                 
                                         

                                                              
                                                     
                              

                              
                                                 


                                            
                                                


                                           
                                                  


                                             
                                                
                                                          

                              
                                                 
                                                                             




                                               
                                                    




                                               
                                                


                                               
                                                  


                                              
                                                 


                                                 
                                               


                                          
                                               


                                          



                                                 



                                                                       



                                                  
                                                                         

                              
                                              


                                         
                                                


                                           

                                                                      





                                                                    





                                                           
                                                                                
                                               

                              

                                                  
                                      
                              
 


                                                                                                       

                                                          
















                                                                         


                              

                                                                                             
 
                      














                                                                                         




                                 
                                                



                                                       
                                               



                                                





                                                  


                                                 
                                                


                                                            
                                                
                              

                              
                                                 


                                                            
                                                 
                              

                              
                                                 


                                          
                                                


                                         
                                                  
                                           
                                               

                              
                                                
                                                    

                              
                                                
                                                   

                              
                                                  


                                            
                                                 


                                                      
                                                

                              
                                               


                                                
                                                       


                              
                                               
                                                
                                                                                                      

                              



                                                 



                                                                       



                                                  
                                                                      

                              
                                              

                                                     
                                                                       
                                                     
                                                                   

                              
                                                  
                                           

                                                               

                              
                                                 
                                      







                                                                                                                                                

                              











                                                                                                       

                        







                                                                      
                              
         



















































































                                                                             
                                                             












                                                                                                           

                                                                                          




                                                                                                           

                                                                                          






                                                                                                           


                                                                                                                                                  


            


                                                                                                                                                  





                                                                                                           

                                                                                          






                                                                                                           


                                                                                                                                                  


            


                                                                                                                                                  





                                                                                                           

                                                                                                                                              







                                                                                               
                                                               
                    
                                                               


            
                                                                    




                                                
                                                               
                    
                                                               










                                                                                               
                                                           
            
                                                                    

                                         
                                                           
            
                                                              






                                                                                                           

                                                                                              











                                                                                                           

                                                                                              











                                                                                                           

                                                   











                                                                                                           

                                                   



















































                                                                                                           
                                                          






                                  
                    
                                                        




                             
                                                                             
 


                     
                                                                                                  
         
                                                   
         
                                                                      
         
                                                                                   





                                                        
                                                           
                 
                                                                   

                                                                
                                                             

                                                                                                       


                                                                       







                                                                                                          

                                                                       




                                                                                            
                                                                              


                                 
                                               



                                                                            



                                                               

                                                               

                                 
 
                                                                         
                         
                                                                                     







                                                                                     
                                                                       







                         
                                                                                        
 


                                                            



                                               

                                               

                 
 
                                                                    
         
                                                 


                                                  
                                                                                






                                                        
                                                           
                 
                                                                   

                                                                
                                                             

                                                                                                       


                                                                     







                                                                                                                            

                                                                       





                                                                                                                  
                                               





                                                                            

                                                       

                         
                                                                         
                         
                                                                                     







                                                                                   
                                                                     















                                                                                     
                                                           



                                                                                     
                                                                     





                                                                             
                                                                     













                                                                                         



                                                                                                         
 



                                                                                                         
 
                                                  
 
                                 

 



                                                                                                                  
 
                                                   
 
                                 




                                                      
                                             


                                                                                   




                                                                                    
                                                  
 
                                          

 
                                            
 
                                                            



                                               

                                                                                                      



                                                                                                                                     
                      
         
                                            

                                                                                                                        
                                                                             
                                                                        
 
                                                                                                                                
                                              


            
                                                    

                                                                                                       
                                                                                       
                                                                        
 
                                                                                                                                          
                                                      


                               
                                                             




                                                                                                                        
                                              

                                        
                                                          
                       
                                                     
                                          

                                                







                                                                                                                       
                                                                                                             


                                                       


                                                                                                                         




                                              
                               
                                    
                                  







                                                                             
                                                  
 
                                                  

 

                                             
                                     
 


                                                                                    













                                 
                          













                                                                      
              

                       






                                      
 


                                


                            

 
                                                   
 
                                     


                                      

                                         
                                                                                                             

                           
                         
 
                                                                                              

                                                                           

                                                                                                 

                                                                             
                                                                                   




















                                                                                               
                  













                                                                                   
      



                                                                                          

                                                                             
                                                                                                                                  

                                                                                       
                                                                                                                                      

                                                                                             
                                                                                                                                        
                                                  

                                
                                                                                 

 
                                             
 
                                                  
                                

 
                                               
 
                                                  
 
                          
                                



                                                 





                                                                                                      
 








                                                                             
                                         
 





                                                               
                                                                     














                                                                                  
                                                        
 




                                                                     
                                                                                           

                              

                                                                                                                     



                                                                                              




                                                                   
                                                      





                                                
 

                                                          
 



                                                                      
 


                                                   



































































                                                                                                      
                                                                           








                                                    



                                                                











                                                                    
                                                                            







                                                                                 

      
/*********************************************************************

    apple2gs.c

    Apple IIgs code


    Apple IIgs specific softswitches:

    C019 - RDVBLBAR
        bits 7 - set during vblank (when at scanline 192 or higher)

    C022 - TBCOLOR
        bits 7-4 - text foreground color
        bits 3-0 - text background color

    C023 - VGCINT
        bit 7 - set for interrupt generated by VGC

        bit 6 - set during one second interrupt
        bit 5 - set during scanline interrupt

        bit 4 - set during external interrupt
        bit 3 - ???
        bit 2 - set for interrupt every second

        bit 1 - set for scanline interrupt
        bit 0 - set for external interrupt

    C025 - KEYMODREG (comes from ?)
        bit 7 - option key pressed
        bit 6 - command key presssed
        bit 5 - modified latch
        bit 4 - keypad key pressed
        bit 3 - repeating
        bit 2 - caps lock latched
        bit 1 - control key pressed
        bit 0 - shift key pressed

    C027 - KMSTATUS (GLU system status)
        bit 7 - set if mouse register full
        bit 6 - mouse interupt enable flag
        bit 5 - set if data register full
        bit 4 - data interrupt enabled
        bit 3 - set if key data full
        bit 2 - key data interurpt enabled
        bit 1 - clear if horizontal mouse data, set if vertical
        bit 0 - command register full

    C029 - NEWVIDEO
        bit 7 - 1 for Super Hi-Res mode, 0 for old Apple II video modes
        bit 6 - 1 to enable memory linearization (2000-9D00 in banks 01/E1), 0 for physical layout
        bit 5 - 1 to display double hi-res mode in monochrome, 0 for color
        bit 4 - ???
        bit 3 - ???
        bit 2 - ???
        bit 1 - ???
        bit 0 - ???

    C02D - SLTROMSEL

    C031 - DISKREG
        bit 7 - set to select head on 3.5" drive
        bit 6 - set to enable 3.5" drive, clear to enable 5.25" drive

    C035 - SHADOW
        bit 7 - ???
        bit 6 - set to inhibit I/O and LC operations ($C000-$FFFF)
        bit 5 - ???
        bit 4 - set to inhibit shadowing aux hires page
        bit 3 - set to inhibit shadowing super hires video
        bit 2 - set to inhibit shadowing hires page 2
        bit 1 - set to inhibit shadowing hires page 2
        bit 0 - set to inhibit shadowing text pages

    C036 - CYAREG
        bit 7 - clear for slow speed, set for hi speed
        bit 6 - ???
        bit 5 - ???
        bit 4 - shadow in all RAM banks
        bit 3 - slot 7 motor on
        bit 2 - slot 6 motor on
        bit 1 - slot 5 motor on
        bit 0 - slot 4 motor on

    C041 - INTEN
        bit 4 - set to enable quarter second interrupts
        bit 3 - set to enable VBL interrupts
        bit 2 - set to enable Mega II mouse switch interrupts
        bit 1 - set to enable Mega II mouse movement interrupts
        bit 0 - set to enable Mega II mouse mouse operation

    C046 - DIAGTYPE/INTFLAG
        bit 7 - set if mouse button currently down
        bit 6 - set if mouse button down on last read
        bit 5 - set for AN3
        bit 4 - set if currently in quarter second interrupt
        bit 3 - set if currently in VBL interrupt
        bit 2 - set if currently in Mega II mouse switch interrupt
        bit 1 - set if currently in Mega II mouse movement interrupt
        bit 0 - set if system IRQ line asserted

    C047 - CLRVBLINT

    C068 - STATEREG
        bit 7 - ALTZP status
        bit 6 - PAGE2 status
        bit 5 - RAMRD status
        bit 4 - RAMWRT status
        bit 3 - !LCRAM status (inverted)
        bit 2 - LCRAM2 status
        bit 1 - ROMBANK status (unimplemented)
        bit 0 - INTCXROM status

*********************************************************************/

#include "emu.h"

#include "includes/apple2gs.h"
#include "includes/apple2.h"
#include "machine/applefdc.h"
#include "machine/sonydriv.h"
#include "machine/8530scc.h"
#include "imagedev/flopdrv.h"
#include "cpu/g65816/g65816.h"
#include "sound/es5503.h"
#include "machine/ram.h"
#include "debugger.h"

#define LOG_C0XX            0
#define LOG_ADB             0
#define LOG_IRQ             0

/* -----------------------------------------------------------------------
 * Apple IIgs clock
 * ----------------------------------------------------------------------- */

void apple2gs_state::process_clock()
{
	UINT8 operation;
	seconds_t current_interval;

	/* update clock_curtime */
	current_interval = machine().time().seconds;
	m_clock_curtime += current_interval - m_clock_curtime_interval;
	m_clock_curtime_interval = current_interval;

	switch(m_clock_mode)
	{
		case CLOCKMODE_IDLE:
			m_clock_read = (m_clock_data >> 7);
			m_clock_reg1 = (m_clock_data >> 2) & 0x03;
			operation = (m_clock_data >> 4) & 0x07;

			if ((m_clock_data & 0x40) == 0x00)
			{
				switch(operation)
				{
					case 0x00:
						/* read/write seconds register */
						m_clock_mode = CLOCKMODE_TIME;
						break;

					case 0x03:
						/* internal registers */
						if (m_clock_reg1 & 0x02)
						{
							m_clock_mode = CLOCKMODE_BRAM2;
							m_clock_reg1 = (m_clock_data & 0x07) << 5;
						}
						else
						{
							m_clock_mode = CLOCKMODE_INTERNALREGS;
						}
						break;

					default:
						//fatalerror("NYI\n");
						break;
				}
			}
			break;

		case CLOCKMODE_BRAM1:
			if (m_clock_read)
				m_clock_data = m_clock_bram[m_clock_reg1];
			else
				m_clock_bram[m_clock_reg1] = m_clock_data;
			m_clock_mode = CLOCKMODE_IDLE;
			break;

		case CLOCKMODE_BRAM2:
			m_clock_reg1 |= (m_clock_data >> 2) & 0x1F;
			m_clock_mode = CLOCKMODE_BRAM1;
			break;

		case CLOCKMODE_INTERNALREGS:
			switch (m_clock_reg1)
			{
				case 0x00:
					/* test register */
					break;

				case 0x01:
					/* write protect register */
					break;
			}
			m_clock_mode = CLOCKMODE_IDLE;
			break;

		case CLOCKMODE_TIME:
			if (m_clock_data & 0x40)
			{
				m_clock_data = m_clock_curtime >> (m_clock_reg1 * 8);
			}
			else
			{
				m_clock_curtime &= ~(0xFF << (m_clock_reg1 * 8));
				m_clock_curtime |= m_clock_data << (m_clock_reg1 * 8);
			}
			m_clock_mode = CLOCKMODE_IDLE;
			break;

		default:
			//fatalerror("NYI\n");
			break;
	}
}

/* -----------------------------------------------------------------------
 * Interrupts
 * ----------------------------------------------------------------------- */

const char *apple2gs_state::apple2gs_irq_name(UINT16 irq_mask)
{
	switch(irq_mask)
	{
		case IRQ_KBD_SRQ:           return "IRQ_KBD_SRQ";
		case IRQ_ADB_DATA:          return "IRQ_ADB_DATA";
		case IRQ_ADB_MOUSE:         return "IRQ_ADB_MOUSE";
		case IRQ_VGC_SCANLINE:      return "IRQ_VGC_SCANLINE";
		case IRQ_VGC_SECOND:        return "IRQ_VGC_SECOND";
		case IRQ_INTEN_QSECOND:     return "IRQ_INTEN_QSECOND";
		case IRQ_INTEN_VBL:         return "IRQ_INTEN_VBL";
		case IRQ_DOC:               return "IRQ_DOC";
		case IRQ_SLOT:              return "IRQ_SLOT";
	}
	return NULL;
}

void apple2gs_state::apple2gs_add_irq(UINT16 irq_mask)
{
	if ((m_pending_irqs & irq_mask) == 0x00)
	{
		if (LOG_IRQ)
			logerror("apple2gs_add_irq(): adding %s\n", apple2gs_irq_name(irq_mask));

		m_pending_irqs |= irq_mask;
		m_maincpu->set_input_line(G65816_LINE_IRQ, m_pending_irqs ? ASSERT_LINE : CLEAR_LINE);
	}
}



void apple2gs_state::apple2gs_remove_irq(UINT16 irq_mask)
{
	if (m_pending_irqs & irq_mask)
	{
		if (LOG_IRQ)
			logerror("apple2gs_remove_irq(): removing %s\n", apple2gs_irq_name(irq_mask));

		m_pending_irqs &= ~irq_mask;
		m_maincpu->set_input_line(G65816_LINE_IRQ, m_pending_irqs ? ASSERT_LINE : CLEAR_LINE);
	}
}

WRITE_LINE_MEMBER(apple2gs_state::apple2gs_doc_irq)
{
	if (state)
	{
		apple2gs_add_irq(IRQ_DOC);
	}
	else
	{
		apple2gs_remove_irq(IRQ_DOC);
	}
}


/* Clock interrupt */
TIMER_CALLBACK_MEMBER(apple2gs_state::apple2gs_clock_tick)
{
	if ((m_vgcint & 0x04) && !(m_vgcint & 0x40))
	{
		m_vgcint |= 0xc0;
		apple2gs_add_irq(IRQ_VGC_SECOND);
	}
}


/* Quarter-second interrupt */
TIMER_CALLBACK_MEMBER(apple2gs_state::apple2gs_qsecond_tick)
{
	if ((m_inten & 0x10) && !(m_intflag & 0x10))
	{
		m_intflag |= 0x10;
		apple2gs_add_irq(IRQ_INTEN_QSECOND);
	}
}


/* -----------------------------------------------------------------------
 * ADB
 * ----------------------------------------------------------------------- */


#if !RUN_ADB_MICRO
UINT8 apple2gs_state::adb_read_memory(UINT32 address)
{
	if (address < ARRAY_LENGTH(m_adb_memory))
		return m_adb_memory[address];
	else
		return 0x00;
}



void apple2gs_state::adb_write_memory(UINT32 address, UINT8 data)
{
	if (address < ARRAY_LENGTH(m_adb_memory))
		m_adb_memory[address] = data;
}



void apple2gs_state::adb_set_mode(UINT8 mode)
{
	m_adb_mode = mode;
}



void apple2gs_state::adb_set_config(UINT8 b1, UINT8 b2, UINT8 b3)
{
	/* ignore for now */
}



void apple2gs_state::adb_post_response(const UINT8 *bytes, size_t length)
{
	assert(length < ARRAY_LENGTH(m_adb_response_bytes));
	memcpy(m_adb_response_bytes, bytes, length);

	m_adb_state = ADBSTATE_INRESPONSE;
	m_adb_response_length = length;
	m_adb_response_pos = 0;
}



void apple2gs_state::adb_post_response_1(UINT8 b)
{
	adb_post_response(&b, 1);
}



void apple2gs_state::adb_post_response_2(UINT8 b1, UINT8 b2)
{
	UINT8 b[2];
	b[0] = b1;
	b[1] = b2;
	adb_post_response(b, 2);
}


void apple2gs_state::adb_do_command()
{
	int device;
	UINT32 address;
	UINT8 val;

	m_adb_state = ADBSTATE_IDLE;
	if (LOG_ADB)
		logerror("adb_do_command(): adb_command=0x%02x\n", m_adb_command);

	switch(m_adb_command)
	{
		case 0x00:  /* ??? */
			break;

		case 0x03:  /* flush keyboard buffer */
			break;

		case 0x04:  /* set modes */
			adb_set_mode(m_adb_mode | m_adb_command_bytes[0]);
			break;

		case 0x05:  /* clear modes */
			adb_set_mode(m_adb_mode & ~m_adb_command_bytes[0]);
			break;

		case 0x06:  /* set config */
			adb_set_config(m_adb_command_bytes[0], m_adb_command_bytes[1], m_adb_command_bytes[2]);
			break;

		case 0x07:  /* synchronize */
			adb_set_mode(m_adb_command_bytes[0]);
			adb_set_config(m_adb_command_bytes[1], m_adb_command_bytes[2], m_adb_command_bytes[3]);
			break;

		case 0x08:  /* write memory */
			address = m_adb_command_bytes[0];
			val = m_adb_command_bytes[1];
			adb_write_memory(address, val);
			break;

		case 0x09:  /* read memory */
			address = (m_adb_command_bytes[1] << 8) | m_adb_command_bytes[0];
			adb_post_response_1(adb_read_memory(address));
			break;

		case 0x0a: /* ??? */
		case 0x0b: /* ??? */
			break;

		case 0x0d:  /* get version */
			adb_post_response_1(0x06);
			break;

		case 0x0e:  /* read available charsets */
			adb_post_response_2(0x01, 0x00);
			break;

		case 0x0f:  /* read available layouts */
			adb_post_response_2(0x01, 0x00);
			break;

		case 0x12:  /* mystery command 0x12 */
		case 0x13:  /* mystery command 0x13 */
			break;

		case 0xb0: case 0xb1: case 0xb2: case 0xb3:
		case 0xb4: case 0xb5: case 0xb6: case 0xb7:
		case 0xb8: case 0xb9: case 0xba: case 0xbb:
		case 0xbc: case 0xbd: case 0xbe: case 0xbf:
			/* send data to device */
			device = m_adb_command & 0x0f;
			if (device == m_adb_address_keyboard)
			{
			}
			else if (device == m_adb_address_mouse)
			{
			}
			break;

		case 0xf2:
			break;

		default:
			fatalerror("ADB command 0x%02x unimplemented\n", m_adb_command);
			break;
	}
	m_adb_kmstatus |= 0x20;
}


UINT8 apple2gs_state::adb_read_datareg()
{
	UINT8 result;

	switch(m_adb_state)
	{
		case ADBSTATE_INRESPONSE:
			result = m_adb_response_bytes[m_adb_response_pos++];
			if (m_adb_response_pos >= m_adb_response_length)
			{
				m_adb_state = ADBSTATE_IDLE;
				m_adb_latent_result = result;
				m_adb_kmstatus &= ~0x20;
			}
			break;

		default:
			result = 0; //m_adb_latent_result & 0x7f;
			break;
	}

	if (LOG_ADB)
		logerror("adb_read_datareg(): result=0x%02x\n", result);

	return result;
}


void apple2gs_state::adb_write_datareg(UINT8 data)
{
	if (LOG_ADB)
		logerror("adb_write_datareg(): data=0x%02x\n", data);

	switch(m_adb_state)
	{
		case ADBSTATE_IDLE:
			m_adb_command = data;
			m_adb_command_length = 0;
			m_adb_command_pos = 0;

//          printf("ADB command %02x\n", data);
			switch(data)
			{
				case 0x00:  /* ??? */
				case 0x01:  /* abort */
					/* do nothing for now */
					break;

				case 0x03:  /* flush keyboard buffer */
					m_adb_command_length = 0;
					break;

				case 0x04:  /* set modes */
				case 0x05:  /* clear modes */
					m_adb_command_length = 1;
					break;

				case 0x06:  /* set config */
					m_adb_command_length = 3;
					break;

				case 0x07:  /* synchronize */
					if (m_is_rom3)
						m_adb_command_length = 8;    // ROM 3 has 8 bytes: mode byte, 3 config bytes, kbd/mouse params, disk eject options
					else
						m_adb_command_length = 4;    // ROM 0/1 has 4 bytes sync
					break;

				case 0x08:  /* write memory */
				case 0x09:  /* read memory */
					m_adb_command_length = 2;
					break;

				case 0x0a:  /* ??? */
				case 0x0b:  /* ??? */
					m_adb_command_length = 0;
					break;

				case 0x0d:  /* get version */
					m_adb_command_length = 0;
					break;

				case 0x0e:  /* read available charsets */
					m_adb_command_length = 0;
					m_adb_state = ADBSTATE_INCOMMAND;    /* HACK */
					break;

				case 0x0f:  /* read available layouts */
					m_adb_command_length = 0;
					m_adb_state = ADBSTATE_INCOMMAND;    /* HACK */
					break;

				case 0x12:  /* mystery command 0x12 */
				case 0x13:  /* mystery command 0x13 */
					m_adb_command_length = 2;
					break;

				case 0x70:  /* disable SRQ device 0 */
				case 0x71:  /* disable SRQ device 1 */
				case 0x72:  /* disable SRQ device 2 */
				case 0x73:  /* disable SRQ device 3 */
					/* ignore for now */
					break;

				case 0xb0: case 0xb1: case 0xb2: case 0xb3:
				case 0xb4: case 0xb5: case 0xb6: case 0xb7:
				case 0xb8: case 0xb9: case 0xba: case 0xbb:
				case 0xbc: case 0xbd: case 0xbe: case 0xbf:
					/* send data to device */
					m_adb_command_length = 2;
					break;

				case 0xf2:
					break;

				default:
					fatalerror("ADB command 0x%02x unimplemented\n", data);
					break;

			}

			if (m_adb_command_length > 0)
			{
				m_adb_state = ADBSTATE_INCOMMAND;
				if (LOG_ADB)
					logerror("adb_write_datareg(): in command length %u\n", (unsigned) m_adb_command_length);
			}
			break;

		case ADBSTATE_INCOMMAND:
			assert(m_adb_command_pos < ARRAY_LENGTH(m_adb_command_bytes));
//          printf("ADB param %02x\n", data);
			m_adb_command_bytes[m_adb_command_pos++] = data;
			break;

		case ADBSTATE_INRESPONSE:
			m_adb_state = ADBSTATE_IDLE;
			break;
	}

	/* do command if necessary */
	if ((m_adb_state == ADBSTATE_INCOMMAND) && (m_adb_command_pos >= m_adb_command_length))
		adb_do_command();
}

// real rom 3 h/w reads 0x90 when idle, 0x98 when key pressed
// current MESS reads back 0xb0 when idle
UINT8 apple2gs_state::adb_read_kmstatus()
{
	return m_adb_kmstatus;
}


void apple2gs_state::adb_write_kmstatus(UINT8 data)
{
	m_adb_kmstatus &= ~0x54;
	m_adb_kmstatus |= data & 0x54;
}



UINT8 apple2gs_state::adb_read_mousedata()
{
	UINT8 result = 0x00;
	UINT8 absolute;
	INT8 delta;

	if (m_adb_kmstatus & 0x80)   // mouse register full
	{
		if (m_adb_kmstatus & 0x02)   // H/V mouse data select
		{
			absolute = m_mouse_y;
			delta = m_mouse_dy;
			m_adb_kmstatus &= ~0x82;
			apple2gs_remove_irq(IRQ_ADB_MOUSE);
		}
		else
		{
			absolute = m_mouse_x;
			delta = m_mouse_dx;
			m_adb_kmstatus |= 0x02;
		}

		if (delta > 63)
			delta = 63;
		else if (delta < -64)
			delta = -64;

		result = (absolute & 0x80) | (delta & 0x7F);
	}
	return result;
}


INT8 apple2gs_state::seven_bit_diff(UINT8 v1, UINT8 v2)
{
	v1 -= v2;
	if (v1 & 0x40)
		v1 |= 0x80;
	else
		v1 &= ~0x80;
	return v1;
}



void apple2gs_state::adb_check_mouse()
{
	UINT8 new_mouse_x, new_mouse_y;

	/* read mouse values */
	if ((m_adb_kmstatus & 0x80) == 0x00)
	{
		new_mouse_x = m_adb_mousex->read();
		new_mouse_y = m_adb_mousey->read();

		if ((m_mouse_x != new_mouse_x) || (m_mouse_y != new_mouse_y))
		{
			m_mouse_dx = seven_bit_diff(new_mouse_x, m_mouse_x);
			m_mouse_dy = seven_bit_diff(new_mouse_y, m_mouse_y);
			m_mouse_x = new_mouse_x;
			m_mouse_y = new_mouse_y;

			m_adb_kmstatus |= 0x80;
			m_adb_kmstatus &= ~0x02;
			if (m_adb_kmstatus & 0x40)
				apple2gs_add_irq(IRQ_ADB_MOUSE);
		}
	}
}
#endif


void apple2gs_state::apple2gs_set_scanint(UINT8 data)
{
	/* second interrupt */
	if ((m_vgcint & 0x40) && !(data & 0x40))
	{
		apple2gs_remove_irq(IRQ_VGC_SECOND);
		m_vgcint &= ~0xC0;
	}

	/* scanline interrupt */
	if ((m_vgcint & 0x20) && !(data & 0x20))
	{
		apple2gs_remove_irq(IRQ_VGC_SCANLINE);
		m_vgcint &= ~0xA0;
	}

	if (m_pending_irqs & (IRQ_VGC_SECOND | IRQ_VGC_SCANLINE))
		m_vgcint |= 0x80;
}


TIMER_CALLBACK_MEMBER(apple2gs_state::apple2gs_scanline_tick)
{
	int scanline;

	scanline = machine().first_screen()->vpos();
	machine().first_screen()->update_partial(scanline);

	/* check scanline interrupt bits if we're in super hi-res and the current scanline is within the active display area */
	if ((m_newvideo & 0x80) && (scanline >= (BORDER_TOP-1)) && (scanline < (200+BORDER_TOP-1)))
	{
		UINT8 scb;

		scb = m_slowmem[0x19D00 + scanline - BORDER_TOP + 1];

		if (scb & 0x40)
		{
			// scanline int flag is set even when the actual interrupt is disabled
			m_vgcint |= 0x20;

			// see if the interrupt is also enabled and trigger it if so
			if (m_vgcint & 0x02)
			{
				m_vgcint |= 0x80;
				apple2gs_add_irq(IRQ_VGC_SCANLINE);
			}
		}
	}

	if (scanline == (192+BORDER_TOP))
	{
		/* VBL interrupt */
		if ((m_inten & 0x08) && !(m_intflag & 0x08))
		{
			m_intflag |= 0x08;
			apple2gs_add_irq(IRQ_INTEN_VBL);
		}
	}

	/* check the mouse status */
	if ((scanline % 8) == 0)
	{
		#if !RUN_ADB_MICRO
		adb_check_mouse();
		#endif

		/* call Apple II interrupt handler */
		if ((machine().first_screen()->vpos() % 8) == 7)
		{
			//apple2_interrupt(m_maincpu);
			/* TODO: check me! */
			machine().first_screen()->update_partial(machine().first_screen()->vpos());
		}
	}

	m_scanline_timer->adjust(machine().first_screen()->time_until_pos((scanline+1)%262, 0));
}



/* -----------------------------------------------------------------------
 * Sound handlers
 * ----------------------------------------------------------------------- */


READ8_MEMBER( apple2gs_state::gssnd_r )
{
	UINT8 ret = 0;

	switch (offset)
	{
		case 0: // control
			ret = m_sndglu_ctrl;
			break;
		case 1: // data read
			ret = m_sndglu_dummy_read;

			if (m_sndglu_ctrl & 0x40)    // docram access
			{
				UINT8 *docram = memregion("es5503")->base();
				m_sndglu_dummy_read = docram[m_sndglu_addr];
			}
			else
			{
				m_sndglu_dummy_read = m_es5503->read(space, m_sndglu_addr);
			}

			if (m_sndglu_ctrl & 0x20)    // auto-increment
			{
				m_sndglu_addr++;
			}
			break;
		case 2: // addr l
			ret = m_sndglu_addr & 0xff;
			break;
		case 3: // addr h
			ret = (m_sndglu_addr >> 8) & 0xff;
			break;
	}

	return ret;
}



WRITE8_MEMBER( apple2gs_state::gssnd_w )
{
	switch (offset)
	{
		case 0: // control
			m_sndglu_ctrl = data & 0x7f; // make sure DOC is never busy
			if (!(m_sndglu_ctrl & 0x40)) // clear hi byte of address pointer on DOC access
			{
				m_sndglu_addr &= 0xff;
			}
			break;
		case 1: // data write
			if (m_sndglu_ctrl & 0x40)    // docram access
			{
				UINT8 *docram = memregion("es5503")->base();
				docram[m_sndglu_addr] = data;
			}
			else
			{
				m_es5503->write(space, m_sndglu_addr, data);
			}

			if (m_sndglu_ctrl & 0x20)    // auto-increment
			{
				m_sndglu_addr++;
			}
			break;
		case 2: // addr l
			m_sndglu_addr &= 0xff00;
			m_sndglu_addr |= data;
			break;
		case 3: // addr h
			m_sndglu_addr &= 0x00ff;
			m_sndglu_addr |= data<<8;
			break;
	}
}

/* -----------------------------------------------------------------------
 * IO handlers
 * ----------------------------------------------------------------------- */

// apple2gs_get_vpos - return the correct vertical counter value for the current scanline,
// keeping borders in mind.

int apple2gs_state::apple2gs_get_vpos()
{
	int result, scan;
	static const UINT8 top_border_vert[BORDER_TOP] =
	{
		0xfa, 0xfa, 0xfa, 0xfa, 0xfb, 0xfb, 0xfb, 0xfb,
		0xfc, 0xfc, 0xfc, 0xfd, 0xfd, 0xfe, 0xfe, 0xff,

	};

	scan = machine().first_screen()->vpos();

	if (scan < BORDER_TOP)
	{
		result = top_border_vert[scan];
	}
	else
	{
		result = scan - BORDER_TOP + 0x100 + 1;
	}

	return result;
}

READ8_MEMBER( apple2gs_state::apple2gs_c0xx_r )
{
	UINT8 result;
	scc8530_t *scc;

	if(space.debugger_access())
	{
		return 0;
	}

	offset &= 0xFF;

	switch(offset)
	{
		#if RUN_ADB_MICRO
		case 0x00:  /* C000 - KEYDATA */
			result = keyglu_816_read(GLU_C000);
			break;

		case 0x10:  /* C010 - KBDSTRB */
			result = keyglu_816_read(GLU_C010);
			break;
		#endif

		case 0x19:  /* C019 - RDVBLBAR */
			result = (space.machine().first_screen()->vpos() >= (192+BORDER_TOP)) ? 0x80 : 0x00;
			break;

		case 0x22:  /* C022 - TBCOLOR */
			result = (m_fgcolor << 4) | m_bgcolor;
			break;

		case 0x23:  /* C023 - VGCINT */
			result = m_vgcint;
			break;

		case 0x24:  /* C024 - MOUSEDATA */
			#if RUN_ADB_MICRO
			result = keyglu_816_read(GLU_MOUSEX);
			#else
			result = adb_read_mousedata();
			#endif
			break;

		case 0x25:  /* C025 - KEYMODREG */
			#if RUN_ADB_MICRO
			result = keyglu_816_read(GLU_KEYMOD);
			#else

			result = 0;
			{
				UINT8 temp = m_kbspecial->read();
				if (temp & 1)   // capslock
				{
					result |= 4;
				}
				if (temp & 6)   // shift
				{
					result |= 1;
				}
				if (temp & 8)   // control
				{
					result |= 2;
				}
				if (temp & 0x10)    // open apple/command
				{
					result |= 0x40;
				}
				if (temp & 0x20)    // option
				{
					result |= 0x80;
				}
				// keypad is a little rough right now
				if (m_lastchar >= 0x28 && m_lastchar <= 0x2d)
				{
					result |= 0x10;
				}
				else if (m_lastchar >= 0x32 && m_lastchar <= 0x3f)
				{
					result |= 0x10;
				}
				else if (m_lastchar >= 0x100 && m_lastchar <= 0x101)
				{
					result |= 0x10;
				}
				else if (m_lastchar >= 0x109 && m_lastchar <= 0x10a)
				{
					result |= 0x10;
				}
			}
#endif
			break;

		case 0x26:  /* C026 - DATAREG */
			#if RUN_ADB_MICRO
			result = keyglu_816_read(GLU_DATA);
			#else
			result = adb_read_datareg();
			#endif
			break;

		case 0x27:  /* C027 - KMSTATUS */
			#if RUN_ADB_MICRO
			result = keyglu_816_read(GLU_SYSSTAT);
			#else
			result = adb_read_kmstatus();
			#endif
			break;

		case 0x29:  /* C029 - NEWVIDEO */
			result = m_newvideo;
			break;

		case 0x2B:  /* C02B - LANGSEL */
			result = m_langsel;
			break;

		case 0x2D:  /* C02D - SLTROMSEL */
			result = m_sltromsel;
			break;

		case 0x2E:  /* C02E - VERTCNT */
			result = apple2gs_get_vpos() >> 1;
			break;

		case 0x2F:  /* C02F - HORIZCNT */
			result = space.machine().first_screen()->hpos() / 11;
			if (result > 0)
			{
				result += 0x40;
			}

			if (apple2gs_get_vpos() & 1)
			{
				result |= 0x80;
			}
			break;

		case 0x31:  /* C031 - DISKREG */
			result = m_fdc_diskreg;
			break;

		case 0x33:  /* C033 - CLOCKDATA */
			result = m_clock_data;
			break;

		case 0x34:  /* C034 - CLOCKCTL */
			result = m_clock_control;
			break;

		case 0x35:  /* C035 - SHADOW */
			result = m_shadow;
			break;

		case 0x36:  /* C036 - CYAREG */
			result = m_cyareg;
			break;

		case 0x38:  /* C038 - SCCBREG */
		case 0x39:  /* C039 - SCCAREG */
		case 0x3A:  /* C03A - SCCBDATA */
		case 0x3B:  /* C03B - SCCADATA */
			scc = space.machine().device<scc8530_t>("scc");
			result = scc->reg_r(space, offset & 0x03);
			break;

		case 0x3C:  /* C03C - SOUNDCTL */
		case 0x3D:  /* C03D - SOUNDDATA */
		case 0x3E:  /* C03E - SOUNDADRL */
		case 0x3F:  /* C03F - SOUNDADRH */
			result = gssnd_r(space, offset & 0x03, mem_mask);
			break;

		case 0x41:  /* C041 - INTEN */
			result = m_inten;
			break;

		case 0x46:  /* C046 - INTFLAG */
			result = m_intflag;
			break;

		case 0x68:  /* C068 - STATEREG */
			result = ((m_flags & VAR_ALTZP) ? 0x80 : 0x00)
			|   ((m_flags & VAR_PAGE2)  ? 0x40 : 0x00)
			|   ((m_flags & VAR_RAMRD)  ? 0x20 : 0x00)
			|   ((m_flags & VAR_RAMWRT) ? 0x10 : 0x00)
			|   ((m_flags & VAR_LCRAM)  ? 0x00 : 0x08)
			|   ((m_flags & VAR_LCRAM2) ? 0x04 : 0x00)
			|   ((m_flags & VAR_INTCXROM)? 0x01 : 0x00);
			break;

		case 0x71: case 0x72: case 0x73:
		case 0x74: case 0x75: case 0x76: case 0x77:
		case 0x78: case 0x79: case 0x7a: case 0x7b:
		case 0x7c: case 0x7d: case 0x7e: case 0x7f:
			offset |= (memregion("maincpu")->bytes() - 1) & ~0x3FFF;
			result = m_rom[offset];
			break;

		case 0x21:  /* C021 - MONOCOLOR */
		case 0x2C:  /* C02C - CHARROM */
			result = 0x00;
			break;

		// slot 6 registers should go to applefdc if slot 6 not "Your Card"
		case 0xe0: case 0xe1: case 0xe2: case 0xe3: case 0xe4: case 0xe5: case 0xe6: case 0xe7:
		case 0xe8: case 0xe9: case 0xea: case 0xeb: case 0xec: case 0xed: case 0xee: case 0xef:
			if ((m_sltromsel & (1 << 6)) == 0)
			{
				result = m_fdc->read(offset);
			}
			else
			{
				result = apple2_c0xx_r(space, offset, 0);
			}
			break;

		default:
			if (offset < 0x80)
			{
				result = apple2_c0xx_r(space, offset, 0);
			}
			else
			{
				result = apple2_c080_r(space, offset, 0);
			}
			break;
	}

	if (LOG_C0XX)
		logerror("apple2gs_c0xx_r(): offset=0x%02x result=0x%02x\n", offset, result);

	return result;
}



WRITE8_MEMBER( apple2gs_state::apple2gs_c0xx_w )
{
	scc8530_t *scc;

	offset &= 0xFF;

	if (LOG_C0XX)
		logerror("apple2gs_c0xx_w(): offset=0x%02x data=0x%02x\n", offset, data);

	switch(offset)
	{
		#if RUN_ADB_MICRO
		case 0x10:
			break;
		#endif

		case 0x22:  /* C022 - TBCOLOR */
			m_fgcolor = (data >> 4) & 0x0F;
			m_bgcolor = (data >> 0) & 0x0F;
			break;

		case 0x23:  /* C023 - VGCINT */
			m_vgcint &= ~0x0F;
			m_vgcint |= data & 0x0F;
			break;

		case 0x24:  /* C024 - MOUSEDATA */
		case 0x25:  /* C025 - KEYMODREG */
		case 0x28:  /* C028 - ROMBANK */
		case 0x2C:  /* C02C - CHARROM */
		case 0x2E:  /* C02E - VERTCNT */
		case 0x2F:  /* C02F - HORIZCNT */
			/* ignore these writes */
			break;

		case 0x26:  /* C026 - DATAREG */
			#if RUN_ADB_MICRO
			keyglu_816_write(GLU_COMMAND, data);
			#else
			adb_write_datareg(data);
			#endif
			break;

		case 0x27:  /* C027 - KMSTATUS */
			#if RUN_ADB_MICRO
			keyglu_816_write(GLU_SYSSTAT, data);
			#else
			adb_write_kmstatus(data);
			#endif
			break;

		case 0x29:  /* C029 - NEWVIDEO */
			m_newvideo = data;
			break;

		case 0x2B:  /* C02B - LANGSEL */
			m_langsel = data;
			break;

		case 0x2D:  /* C02D - SLTROMSEL */
			m_sltromsel = data;
			apple2_update_memory();
			break;

		case 0x31:  /* C031 - DISKREG */
			apple2_iwm_setdiskreg(data);
			break;

		case 0x32:  /* C032 - SCANINT */
			apple2gs_set_scanint(data);
			break;

		case 0x33:  /* C033 - CLOCKDATA */
			m_clock_data = data;
			break;

		case 0x34:  /* C034 - CLOCKCTL */
			m_clock_control = data & 0x7F;
			m_bordercolor = data & 0x0F;
			if (data & 0x80)
				process_clock();
			break;

		case 0x35:  /* C035 - SHADOW */
			if (m_shadow != data)
			{
				m_shadow = data;
				apple2_update_memory();
			}
			break;

		case 0x36:  /* C036 - CYAREG */
			m_cyareg = data & ~0x20;
			m_maincpu->set_unscaled_clock((data & 0x80) ? APPLE2GS_14M/5 : APPLE2GS_7M/7);
			break;

		case 0x38:  /* C038 - SCCBREG */
		case 0x39:  /* C039 - SCCAREG */
		case 0x3A:  /* C03A - SCCBDATA */
		case 0x3B:  /* C03B - SCCADATA */
			scc = space.machine().device<scc8530_t>("scc");
			scc->reg_w(space, offset & 0x03, data);
			break;

		case 0x3C:  /* C03C - SOUNDCTL */
		case 0x3D:  /* C03D - SOUNDDATA */
		case 0x3E:  /* C03E - SOUNDADRL */
		case 0x3F:  /* C03F - SOUNDADRH */
			gssnd_w(space, offset & 0x03, data, mem_mask);
			break;

		case 0x41:  /* C041 - INTEN */
			m_inten = data & 0x1F;
			if ((m_inten & 0x10) == 0x00)
				apple2gs_remove_irq(IRQ_INTEN_QSECOND);
			if ((m_inten & 0x08) == 0x00)
				apple2gs_remove_irq(IRQ_INTEN_VBL);
			break;

		case 0x47:  /* C047 - CLRVBLINT */
			m_intflag &= ~0x18;
			apple2gs_remove_irq(IRQ_INTEN_QSECOND);
			apple2gs_remove_irq(IRQ_INTEN_VBL);
			break;

		case 0x68:  /* C068 - STATEREG */
			apple2_setvar(
							((data & 0x80) ? VAR_ALTZP : 0) |
							((data & 0x40) ? VAR_PAGE2 : 0) |
							((data & 0x20) ? VAR_RAMRD : 0) |
							((data & 0x10) ? VAR_RAMWRT : 0) |
							((data & 0x08) ? 0 : VAR_LCRAM) |
							((data & 0x04) ? VAR_LCRAM2 : 0) |
							((data & 0x01) ? VAR_INTCXROM : 0),
							VAR_ALTZP | VAR_PAGE2 | VAR_RAMRD | VAR_RAMWRT | VAR_LCRAM | VAR_LCRAM2 | VAR_INTCXROM);
			break;

		// slot 6 registers should go to applefdc if slot 6 not "Your Card"
		case 0xe0: case 0xe1: case 0xe2: case 0xe3: case 0xe4: case 0xe5: case 0xe6: case 0xe7:
		case 0xe8: case 0xe9: case 0xea: case 0xeb: case 0xec: case 0xed: case 0xee: case 0xef:
			if ((m_sltromsel & (1 << 6)) == 0)
			{
				m_fdc->write(offset, data);
			}
			else
			{
				apple2_c0xx_w(space, offset, data, 0);
			}
			break;

		default:
			if (offset < 0x80)
			{
				apple2_c0xx_w(space, offset, data, 0);
			}
			else
			{
				apple2_c080_w(space, offset, data, 0);
			}
			break;
	}
}



/* -----------------------------------------------------------------------
 * Memory management
 * ----------------------------------------------------------------------- */

WRITE8_MEMBER( apple2gs_state::apple2gs_main0400_w )
{
	offset += 0x000400;
	m_rambase[offset] = data;

	if (!(m_shadow & 0x01))
	{
		m_slowmem[offset] = data;
	}
}

WRITE8_MEMBER( apple2gs_state::apple2gs_aux0400_w )
{
	offset += 0x010400;
	m_rambase[offset] = data;

	if (!(m_shadow & 0x01))
	{
		m_slowmem[offset] = data;
	}
}

WRITE8_MEMBER( apple2gs_state::apple2gs_main2000_w )
{
	offset += 0x002000;
	m_rambase[offset] = data;

	if (!(m_shadow & 0x02))
	{
		m_slowmem[offset] = data;
	}
}

WRITE8_MEMBER( apple2gs_state::apple2gs_aux2000_w )
{
	offset += 0x012000;
	m_rambase[offset] = data;

	if (!(m_shadow & 0x12) || !(m_shadow & 0x08))
	{
		m_slowmem[offset] = data;
	}
}

WRITE8_MEMBER( apple2gs_state::apple2gs_main4000_w )
{
	offset += 0x004000;
	m_rambase[offset] = data;

	if ((offset >= 0x004000) && (offset <= 0x005FFF))
	{
		if (!(m_shadow & 0x04))
			m_slowmem[offset] = data;
	}
}

WRITE8_MEMBER( apple2gs_state::apple2gs_aux4000_w )
{
	offset += 0x014000;
	m_rambase[offset] = data;

	if ((offset >= 0x014000) && (offset <= 0x015FFF))
	{
		if (!(m_shadow & 0x14) || !(m_shadow & 0x08))
			m_slowmem[offset] = data;
	}
	else if ((offset >= 0x016000) && (offset <= 0x019FFF))
	{
		if (!(m_shadow & 0x08))
		{
			m_slowmem[offset] = data;

			if (offset >= 0x19e00)
			{
				int color = (offset - 0x19e00) >> 1;

				m_shr_palette[color] = rgb_t(
					((m_slowmem[0x19E00 + (color * 2) + 1] >> 0) & 0x0F) * 17,
					((m_slowmem[0x19E00 + (color * 2) + 0] >> 4) & 0x0F) * 17,
					((m_slowmem[0x19E00 + (color * 2) + 0] >> 0) & 0x0F) * 17);
			}
		}
	}
}



static void apple2gs_mem_000000(running_machine &machine,offs_t begin, offs_t end, apple2_meminfo *meminfo)
{
	apple2gs_state *state = machine.driver_data<apple2gs_state>();
	meminfo->read_mem           = (state->m_flags & VAR_ALTZP)  ? 0x010000 : 0x000000;
	meminfo->write_mem          = (state->m_flags & VAR_ALTZP)  ? 0x010000 : 0x000000;
}

static void apple2gs_mem_000200(running_machine &machine,offs_t begin, offs_t end, apple2_meminfo *meminfo)
{
	apple2gs_state *state = machine.driver_data<apple2gs_state>();
	meminfo->read_mem           = (state->m_flags & VAR_RAMRD)  ? 0x010200 : 0x000200;
	meminfo->write_mem          = (state->m_flags & VAR_RAMWRT) ? 0x010200 : 0x000200;
}

static void apple2gs_mem_000400(running_machine &machine,offs_t begin, offs_t end, apple2_meminfo *meminfo)
{
	apple2gs_state *state = machine.driver_data<apple2gs_state>();
	if (state->m_flags & VAR_80STORE)
	{
		meminfo->read_mem       = (state->m_flags & VAR_PAGE2)  ? 0x010400 : 0x000400;
		meminfo->write_mem      = (state->m_flags & VAR_PAGE2)  ? 0x010400 : 0x000400;
		meminfo->write_handler  = (state->m_flags & VAR_PAGE2)  ? &state->write_delegates_2gs0400[0] : &state->write_delegates_2gs0400[1];
	}
	else
	{
		meminfo->read_mem       = (state->m_flags & VAR_RAMRD)  ? 0x010400 : 0x000400;
		meminfo->write_mem      = (state->m_flags & VAR_RAMWRT) ? 0x010400 : 0x000400;
		meminfo->write_handler  = (state->m_flags & VAR_RAMWRT) ? &state->write_delegates_2gs0400[0] : &state->write_delegates_2gs0400[1];
	}
}

static void apple2gs_mem_000800(running_machine &machine,offs_t begin, offs_t end, apple2_meminfo *meminfo)
{
	apple2gs_state *state = machine.driver_data<apple2gs_state>();
	meminfo->read_mem           = (state->m_flags & VAR_RAMRD)  ? 0x010800 : 0x000800;
	meminfo->write_mem          = (state->m_flags & VAR_RAMWRT) ? 0x010800 : 0x000800;
}

static void apple2gs_mem_002000(running_machine &machine,offs_t begin, offs_t end, apple2_meminfo *meminfo)
{
	apple2gs_state *state = machine.driver_data<apple2gs_state>();
	if ((state->m_flags & (VAR_80STORE|VAR_HIRES)) == (VAR_80STORE|VAR_HIRES))
	{
		meminfo->read_mem       = (state->m_flags & VAR_PAGE2)  ? 0x012000 : 0x002000;
		meminfo->write_mem      = (state->m_flags & VAR_PAGE2)  ? 0x012000 : 0x002000;
		meminfo->write_handler  = (state->m_flags & VAR_PAGE2)  ? &state->write_delegates_2gs2000[0] : &state->write_delegates_2gs2000[1];
	}
	else
	{
		meminfo->read_mem       = (state->m_flags & VAR_RAMRD)  ? 0x012000 : 0x002000;
		meminfo->write_mem      = (state->m_flags & VAR_RAMWRT) ? 0x012000 : 0x002000;
		meminfo->write_handler  = (state->m_flags & VAR_RAMWRT) ? &state->write_delegates_2gs2000[0] : &state->write_delegates_2gs2000[1];
	}
}

static void apple2gs_mem_004000(running_machine &machine,offs_t begin, offs_t end, apple2_meminfo *meminfo)
{
	apple2gs_state *state = machine.driver_data<apple2gs_state>();
	meminfo->read_mem           = (state->m_flags & VAR_RAMRD)  ? 0x014000 : 0x004000;
	meminfo->write_handler      = (state->m_flags & VAR_RAMWRT) ? &state->write_delegates_2gs4000[0] : &state->write_delegates_2gs4000[1];
}

static void apple2gs_mem_xxD000(running_machine &machine,apple2_meminfo *meminfo, UINT32 lcmem)
{
	apple2gs_state *state = machine.driver_data<apple2gs_state>();
	if (state->m_flags & VAR_LCRAM)
	{
		if (state->m_flags & VAR_LCRAM2)
			meminfo->read_mem   = lcmem | 0x00C000;
		else
			meminfo->read_mem   = lcmem | 0x00D000;
	}
	else
	{
		meminfo->read_mem       = 0x03D000 | APPLE2_MEM_ROM;
	}

	if (state->m_flags & VAR_LCWRITE)
	{
		if (state->m_flags & VAR_LCRAM2)
			meminfo->write_mem  = lcmem | 0x00C000;
		else
			meminfo->write_mem  = lcmem | 0x00D000;
	}
	else
	{
		meminfo->write_mem = APPLE2_MEM_FLOATING;
	}
}

static void apple2gs_mem_xxE000(running_machine &machine,apple2_meminfo *meminfo, UINT32 lcmem)
{
	apple2gs_state *state = machine.driver_data<apple2gs_state>();
	if (state->m_flags & VAR_LCRAM)
		meminfo->read_mem       = lcmem | 0x00E000;
	else
		meminfo->read_mem       = 0x03E000 | APPLE2_MEM_ROM;

	if (state->m_flags & VAR_LCWRITE)
		meminfo->write_mem      = lcmem | 0x00E000;
	else
		meminfo->write_mem      = APPLE2_MEM_FLOATING;
}

static void apple2gs_mem_00D000(running_machine &machine,offs_t begin, offs_t end, apple2_meminfo *meminfo)
{
	apple2gs_state *state = machine.driver_data<apple2gs_state>();
	if (state->m_shadow & 0x40)
	{
		meminfo->read_mem       = (state->m_flags & VAR_RAMRD) ? 0x01D000 : 0x00D000;
		meminfo->write_mem      = (state->m_flags & VAR_RAMWRT) ? 0x01D000 : 0x00D000;
	}
	else
	{
		apple2gs_mem_xxD000(machine,meminfo, (state->m_flags & VAR_ALTZP) ? 0x010000 : 0x000000);
	}
}

static void apple2gs_mem_00E000(running_machine &machine,offs_t begin, offs_t end, apple2_meminfo *meminfo)
{
	apple2gs_state *state = machine.driver_data<apple2gs_state>();
	if (state->m_shadow & 0x40)
	{
		meminfo->read_mem       = (state->m_flags & VAR_RAMRD) ? 0x01E000 : 0x00E000;
		meminfo->write_mem      = (state->m_flags & VAR_RAMWRT) ? 0x01E000 : 0x00E000;
	}
	else
	{
		apple2gs_mem_xxE000(machine,meminfo, (state->m_flags & VAR_ALTZP) ? 0x010000 : 0x000000);
	}
}

static void apple2gs_mem_01D000(running_machine &machine,offs_t begin, offs_t end, apple2_meminfo *meminfo)
{
	apple2gs_state *state = machine.driver_data<apple2gs_state>();
	if (state->m_shadow & 0x40)
	{
		meminfo->read_mem       = 0x01D000;
		meminfo->write_mem      = 0x01D000;
	}
	else
	{
		apple2gs_mem_xxD000(machine,meminfo, 0x010000);
	}
}

static void apple2gs_mem_01E000(running_machine &machine,offs_t begin, offs_t end, apple2_meminfo *meminfo)
{
	apple2gs_state *state = machine.driver_data<apple2gs_state>();
	if (state->m_shadow & 0x40)
	{
		meminfo->read_mem       = 0x01E000;
		meminfo->write_mem      = 0x01E000;
	}
	else
	{
		apple2gs_mem_xxE000(machine,meminfo, 0x010000);
	}
}

static void apple2gs_mem_E0D000(running_machine &machine,offs_t begin, offs_t end, apple2_meminfo *meminfo)
{
	apple2gs_mem_xxD000(machine,meminfo, 0x000000 | APPLE2_MEM_AUX);
}

static void apple2gs_mem_E0E000(running_machine &machine,offs_t begin, offs_t end, apple2_meminfo *meminfo)
{
	apple2gs_mem_xxE000(machine,meminfo, 0x000000 | APPLE2_MEM_AUX);
}

static void apple2gs_mem_E1D000(running_machine &machine,offs_t begin, offs_t end, apple2_meminfo *meminfo)
{
	apple2gs_mem_xxD000(machine,meminfo, 0x010000 | APPLE2_MEM_AUX);
}

static void apple2gs_mem_E1E000(running_machine &machine,offs_t begin, offs_t end, apple2_meminfo *meminfo)
{
	apple2gs_mem_xxE000(machine,meminfo, 0x010000 | APPLE2_MEM_AUX);
}



static const apple2_memmap_entry apple2gs_memmap_entries[] =
{
	{ 0x000000, 0x0001FF, apple2gs_mem_000000, A2MEM_MONO },
	{ 0x000200, 0x0003FF, apple2gs_mem_000200, A2MEM_DUAL },
	{ 0x000400, 0x0007FF, apple2gs_mem_000400, A2MEM_DUAL },
	{ 0x000800, 0x001FFF, apple2gs_mem_000800, A2MEM_DUAL },
	{ 0x002000, 0x003FFF, apple2gs_mem_002000, A2MEM_DUAL },
	{ 0x004000, 0x00BFFF, apple2gs_mem_004000, A2MEM_DUAL },
	{ 0x00D000, 0x00DFFF, apple2gs_mem_00D000, A2MEM_DUAL },
	{ 0x00E000, 0x00FFFF, apple2gs_mem_00E000, A2MEM_DUAL },

	{ 0x01D000, 0x01DFFF, apple2gs_mem_01D000, A2MEM_DUAL },
	{ 0x01E000, 0x01FFFF, apple2gs_mem_01E000, A2MEM_DUAL },
	{ 0xE0D000, 0xE0DFFF, apple2gs_mem_E0D000, A2MEM_DUAL },
	{ 0xE0E000, 0xE0FFFF, apple2gs_mem_E0E000, A2MEM_DUAL },
	{ 0xE1D000, 0xE1DFFF, apple2gs_mem_E1D000, A2MEM_DUAL },
	{ 0xE1E000, 0xE1FFFF, apple2gs_mem_E1E000, A2MEM_DUAL },

	{ 0 }
};



UINT8 *apple2gs_state::apple2gs_getslotmem(offs_t address)
{
	UINT8 *rom;

	address %= 0x00FFFF;
	assert(address >= 0xC000);
	assert(address <= 0xCFFF);

	rom = m_rom;
	rom += 0x030000 % memregion("maincpu")->bytes();
	return &rom[address];
}



UINT8 apple2gs_state::apple2gs_xxCxxx_r(address_space &space, offs_t address)
{
	UINT8 result;
	int slot;

	if ((m_shadow & 0x40) && ((address & 0xF00000) == 0x000000)) // shadow all banks and C0xx?
	{
		result = m_ram->pointer()[address];
	}
	else if ((address & 0x000F00) == 0x000000)  // accessing C0xx?
	{
		result = apple2gs_c0xx_r(m_maincpu->space(AS_PROGRAM), address, 0);
	}
	else
	{
		device_a2bus_card_interface *slotdevice;

		slot = (address & 0x000F00) / 0x100;
		if (slot <= 7)  // slots 1-7, it's the slot
		{
			slotdevice = m_a2bus->get_a2bus_card(slot);

			// is this slot internal or "Your Card"?
			if ((m_sltromsel & (1 << slot)) == 0)
			{
				// accessing a slot mapped to internal, let's put back the internal ROM
				m_a2_cnxx_slot = -1;
				apple2_update_memory();
				result = *apple2gs_getslotmem(address);
			}
			else
			{
				// accessing a slot mapped to "Your Card", C800 should belong to that card
				if (slotdevice != NULL)
				{
					if (slotdevice->take_c800())
					{
						m_a2_cnxx_slot = slot;
						apple2_update_memory();
					}
					result = slotdevice->read_cnxx(space, address&0xff);
				}
				else
				{
					result = apple2_getfloatingbusvalue();
				}
			}
		}
		else    // C800-CFFF, not cards
		{
			slotdevice = NULL;

			// if CFFF accessed, reset C800 area to internal ROM
			if(!space.debugger_access())
			{
				if ((address & 0xfff) == 0xfff)
				{
					m_a2_cnxx_slot = -1;
					apple2_update_memory();
				}
			}

			if ( m_a2_cnxx_slot >= 0 && m_a2_cnxx_slot <= 7 )
			{
				slotdevice = m_a2bus->get_a2bus_card(m_a2_cnxx_slot);
			}

			if (slotdevice)
			{
				result = slotdevice->read_c800(space, address&0x7ff);
			}
			else
			{
				result = *apple2gs_getslotmem(address);
			}
		}
	}
	return result;
}



void apple2gs_state::apple2gs_xxCxxx_w(address_space &space, offs_t address, UINT8 data)
{
	int slot;

	// if CFFF accessed, reset C800 area to internal ROM
	if(!space.debugger_access())
	{
		if ((address & 0xfff) == 0xfff)
		{
			m_a2_cnxx_slot = -1;
			apple2_update_memory();
		}
	}

	if ((m_shadow & 0x40) && ((address & 0xF00000) == 0x000000))
	{
		m_ram->pointer()[address] = data;
	}
	else if ((address & 0x000F00) == 0x000000)
	{
		apple2gs_c0xx_w(m_maincpu->space(AS_PROGRAM), address, data, 0);
	}
	else
	{
		device_a2bus_card_interface *slotdevice;

		slot = (address & 0x000F00) / 0x100;

		if (slot <= 7)  // slots 1-7, it's the slot
		{
			slotdevice = m_a2bus->get_a2bus_card(slot);

			// is this slot internal or "Your Card"?
			if ((m_sltromsel & (1 << slot)) == 0)
			{
				// accessing a slot mapped to internal, let's put back the internal ROM
				m_a2_cnxx_slot = -1;
				apple2_update_memory();
				*apple2gs_getslotmem(address) = data;
			}
			else
			{
				// accessing a slot mapped to "Your Card", C800 should belong to that card if it can take it
				if (slotdevice != NULL)
				{
					if (slotdevice->take_c800())
					{
						m_a2_cnxx_slot = slot;
						apple2_update_memory();
					}
					slotdevice->write_cnxx(space, address&0xff, data);
				}
				// (else slot is your card but there's no card inserted so the write goes nowhere)
			}
		}
		else    // C800-CFFF, not cards
		{
			slotdevice = NULL;

			// if CFFF accessed, reset C800 area to internal ROM
			if ((address & 0xfff) == 0xfff)
			{
				m_a2_cnxx_slot = -1;
				apple2_update_memory();
			}

			if ( m_a2_cnxx_slot >= 0 && m_a2_cnxx_slot <= 7 )
			{
				slotdevice = m_a2bus->get_a2bus_card(m_a2_cnxx_slot);
			}

			if (slotdevice)
			{
				slotdevice->write_c800(space, address&0x7ff, data);
			}
			else
			{
				*apple2gs_getslotmem(address) = data;
			}
		}
	}
}



DIRECT_UPDATE_MEMBER(apple2gs_state::apple2gs_opbase)
{
	UINT8 *opptr = NULL;
	int slot;

	if (((address & 0xFEF000) == 0x00C000) || ((address & 0xFEF000) == 0xE0C000))
	{
		if ((m_shadow & 0x40) && ((address & 0xF00000) == 0x000000))
		{
			opptr = &m_ram->pointer()[address];
		}
		else if ((address & 0x000F00) == 0x000000)
		{
			if (((address & 0xFF) >= 0x71) && ((address & 0xFF) <= 0x7F))
				opptr = apple2gs_getslotmem(address);
		}
		else
		{
			slot = (address & 0x000F00) / 0x100;

			if ((slot > 7) || ((m_sltromsel & (1 << slot)) == 0))
				opptr = apple2gs_getslotmem(address);
		}

		if (opptr != NULL)
		{
			direct.explicit_configure(address, address, ~0, opptr - address);

			address = ~0;
		}
	}
	return address;
}



READ8_MEMBER( apple2gs_state::apple2gs_00Cxxx_r ) { return apple2gs_xxCxxx_r(space, offset | 0x00C000); }
READ8_MEMBER( apple2gs_state::apple2gs_01Cxxx_r ) { return apple2gs_xxCxxx_r(space, offset | 0x01C000); }
READ8_MEMBER( apple2gs_state::apple2gs_E0Cxxx_r ) { return apple2gs_xxCxxx_r(space, offset | 0xE0C000); }
READ8_MEMBER( apple2gs_state::apple2gs_E1Cxxx_r ) { return apple2gs_xxCxxx_r(space, offset | 0xE1C000); }

WRITE8_MEMBER( apple2gs_state::apple2gs_00Cxxx_w ) { apple2gs_xxCxxx_w(space, offset | 0x00C000, data); }
WRITE8_MEMBER( apple2gs_state::apple2gs_01Cxxx_w ) { apple2gs_xxCxxx_w(space, offset | 0x01C000, data); }
WRITE8_MEMBER( apple2gs_state::apple2gs_E0Cxxx_w ) { apple2gs_xxCxxx_w(space, offset | 0xE0C000, data); }
WRITE8_MEMBER( apple2gs_state::apple2gs_E1Cxxx_w ) { apple2gs_xxCxxx_w(space, offset | 0xE1C000, data); }

WRITE8_MEMBER( apple2gs_state::apple2gs_Exxxxx_w )
{
	m_slowmem[offset] = data;
}

WRITE8_MEMBER( apple2gs_state::apple2gs_E004xx_w ) { apple2gs_Exxxxx_w(space, offset + 0x00400, data, mem_mask); }
WRITE8_MEMBER( apple2gs_state::apple2gs_E02xxx_w ) { apple2gs_Exxxxx_w(space, offset + 0x02000, data, mem_mask); }
WRITE8_MEMBER( apple2gs_state::apple2gs_E104xx_w ) { apple2gs_Exxxxx_w(space, offset + 0x10400, data, mem_mask); }
WRITE8_MEMBER( apple2gs_state::apple2gs_E12xxx_w ) { apple2gs_Exxxxx_w(space, offset + 0x12000, data, mem_mask); }

WRITE8_MEMBER( apple2gs_state::apple2gs_slowmem_w )
{
	m_slowmem[offset] = data;

	if ((offset >= 0x19e00) && (offset < 0x19fff))
	{
		int color = (offset - 0x19e00) >> 1;

		m_shr_palette[color] = rgb_t(
			((m_slowmem[0x19E00 + (color * 2) + 1] >> 0) & 0x0F) * 17,
			((m_slowmem[0x19E00 + (color * 2) + 0] >> 4) & 0x0F) * 17,
			((m_slowmem[0x19E00 + (color * 2) + 0] >> 0) & 0x0F) * 17);
	}
}

// Because the bank address multiplexes on the 65816 data bus, reading a memory area
// which doesn't drive the bus results in reading back the bank number.
READ8_MEMBER(apple2gs_state::apple2gs_bank_echo_r)
{
	return m_echo_bank + (offset>>16);
}

void apple2gs_state::apple2gs_setup_memory()
{
	address_space& space = m_maincpu->space(AS_PROGRAM);
	offs_t begin, end;
	apple2_memmap_config cfg;

	/* allocate memory for E00000-E1FFFF */
	m_slowmem = auto_alloc_array_clear(machine(), UINT8, 128*1024);
	state_save_register_item_pointer(machine(), "APPLE2GS_SLOWMEM", NULL, 0, m_slowmem, 128*1024);

	// install expanded memory
	// fair warning: other code assumes banks 0 and 1 are the first 128k of the RAM device, so you must install bank 1 at 0x10000
	// otherwise nothing works :)
	if (m_is_rom3)
	{
		int ramsize = m_ram->size();

		// ROM 03 hardware: the quoted "1 MB" for a base machine doesn't include banks e0/e1, so map accordingly
		space.install_readwrite_bank(0x010000, ramsize - 1, "bank1");
		membank("bank1")->set_base(m_ram->pointer() + 0x010000);

		space.install_read_handler( ramsize, 0xdfffff, read8_delegate(FUNC(apple2gs_state::apple2gs_bank_echo_r),this));
		m_echo_bank = (ramsize >> 16);
	}
	else
	{
		int ramsize = m_ram->size()-0x30000;

		// ROM 00/01 hardware: the quoted "256K" for a base machine *does* include banks e0/e1.
		space.install_readwrite_bank(0x010000, ramsize - 1 + 0x10000, "bank1");
		membank("bank1")->set_base(m_ram->pointer() + 0x010000);

		space.install_read_handler( ramsize + 0x10000, 0xdfffff, read8_delegate(FUNC(apple2gs_state::apple2gs_bank_echo_r),this));
		m_echo_bank = (ramsize+0x10000) >> 16;
	}

	/* install hi memory */
	space.install_read_bank(0xe00000, 0xe1ffff, "bank2");
	space.install_write_handler(0xe00000, 0xe1ffff, write8_delegate(FUNC(apple2gs_state::apple2gs_slowmem_w),this));
	space.install_write_handler(0xe00400, 0xe007ff, write8_delegate(FUNC(apple2gs_state::apple2gs_E004xx_w),this));
	space.install_write_handler(0xe02000, 0xe03fff, write8_delegate(FUNC(apple2gs_state::apple2gs_E02xxx_w),this));
	space.install_write_handler(0xe10400, 0xe107ff, write8_delegate(FUNC(apple2gs_state::apple2gs_E104xx_w),this));
	space.install_write_handler(0xe12000, 0xe13fff, write8_delegate(FUNC(apple2gs_state::apple2gs_E12xxx_w),this));
	membank("bank2")->set_base(m_slowmem);

	/* install alternate ROM bank */
	begin = 0x1000000 - memregion("maincpu")->bytes();
	end = 0xffffff;
	space.install_read_bank(begin, end, "bank3");
	membank("bank3")->set_base(m_rom);

	/* install new xxC000-xxCFFF handlers */
	space.install_read_handler(0x00c000, 0x00cfff, read8_delegate(FUNC(apple2gs_state::apple2gs_00Cxxx_r),this));
	space.install_write_handler(0x00c000, 0x00cfff, write8_delegate(FUNC(apple2gs_state::apple2gs_00Cxxx_w),this));
	space.install_read_handler(0x01c000, 0x01cfff, read8_delegate(FUNC(apple2gs_state::apple2gs_01Cxxx_r),this));
	space.install_write_handler(0x01c000, 0x01cfff, write8_delegate(FUNC(apple2gs_state::apple2gs_01Cxxx_w),this));
	space.install_read_handler(0xe0c000, 0xe0cfff, read8_delegate(FUNC(apple2gs_state::apple2gs_E0Cxxx_r),this));
	space.install_write_handler(0xe0c000, 0xe0cfff, write8_delegate(FUNC(apple2gs_state::apple2gs_E0Cxxx_w),this));
	space.install_read_handler(0xe1c000, 0xe1cfff, read8_delegate(FUNC(apple2gs_state::apple2gs_E1Cxxx_r),this));
	space.install_write_handler(0xe1c000, 0xe1cfff, write8_delegate(FUNC(apple2gs_state::apple2gs_E1Cxxx_w),this));
	space.set_direct_update_handler(direct_update_delegate(FUNC(apple2gs_state::apple2gs_opbase), this));


	/* install aux memory writes (for shadowing) */
	space.install_write_handler(0x010400, 0x0107FF, write8_delegate(FUNC(apple2gs_state::apple2gs_aux0400_w), this));
	space.install_write_handler(0x012000, 0x013FFF, write8_delegate(FUNC(apple2gs_state::apple2gs_aux2000_w), this));
	space.install_write_handler(0x014000, 0x019FFF, write8_delegate(FUNC(apple2gs_state::apple2gs_aux4000_w), this));

	/* setup the Apple II memory system */
	memset(&cfg, 0, sizeof(cfg));
	cfg.first_bank = 4;
	cfg.memmap = apple2gs_memmap_entries;
	cfg.auxmem = m_slowmem;
	cfg.auxmem_length = 0x20000;
	apple2_setup_memory(&cfg);
}



/* -----------------------------------------------------------------------
 * Driver Init
 * ----------------------------------------------------------------------- */

READ8_MEMBER(apple2gs_state::apple2gs_read_vector)
{
	return space.read_byte(offset | 0xFF0000);
}

MACHINE_RESET_MEMBER(apple2gs_state,apple2gs)
{
	apple2gs_refresh_delegates();

	// call "base class" machine reset to set up m_rambase and the language card
	machine_reset();

	m_cur_slot6_image = NULL;
	m_newvideo = 0x00;
	m_vgcint = 0x00;
	m_langsel = 0x00;
	m_sltromsel = 0x00;
	m_cyareg = 0x80;
	m_inten = 0x00;
	m_intflag = 0x00;
	m_shadow = 0x00;
	m_pending_irqs = 0x00;
	m_mouse_x = 0x00;
	m_mouse_y = 0x00;
	m_mouse_dx = 0x00;
	m_mouse_dy = 0x00;
	#if !RUN_ADB_MICRO
	m_adb_state = ADBSTATE_IDLE;
	m_adb_kmstatus = 0x00;
	m_adb_command = 0;
	m_adb_mode = 0;
	m_adb_latent_result = 0;
	m_adb_command_length = 0;
	m_adb_command_pos = 0;
	memset(m_adb_command_bytes, 0, sizeof(m_adb_command_bytes));
	memset(m_adb_response_bytes, 0, sizeof(m_adb_response_bytes));
	m_adb_response_length = 0;
	m_adb_response_pos = 0;
	memset(m_adb_memory, 0, sizeof(m_adb_memory));
	m_adb_address_keyboard = 2;
	m_adb_address_mouse = 3;
	#endif

	/* init time */
	m_clock_data = 0;
	m_clock_control =0;
	m_clock_read = 0;
	m_clock_reg1 = 0;
	m_clock_mode = CLOCKMODE_IDLE;
	m_clock_curtime = 0;
	m_clock_curtime_interval = 0;

	m_sndglu_ctrl = 0x00;
	m_sndglu_addr = 0;
	m_sndglu_dummy_read = 0;

	m_adb_dtime = 0;
	m_last_adb_time = 0;
}

MACHINE_START_MEMBER(apple2gs_state,apple2gscommon)
{
	apple2gs_refresh_delegates();

	m_machinetype = APPLE_IIGS;
	apple2eplus_init_common(NULL);

	/* set up Apple IIgs vectoring */
	m_maincpu->set_read_vector_callback(read8_delegate(FUNC(apple2gs_state::apple2gs_read_vector),this));

	/* setup globals */
	m_is_rom3 = true;

	machine().device<nvram_device>("nvram")->set_base(m_clock_bram, sizeof(m_clock_bram));

	/* save state stuff.  note that the driver takes care of docram. */
	UINT8* ram = m_ram->pointer();
	state_save_register_item_pointer(machine(), "APPLE2GS_RAM", NULL, 0, ram, m_ram->size());

	state_save_register_item(machine(), "NEWVIDEO", NULL, 0, m_newvideo);
	state_save_register_item(machine(), "BORDERCOLOR", NULL, 0, m_bordercolor);
	state_save_register_item(machine(), "VGCINT", NULL,0, m_vgcint);
	state_save_register_item(machine(), "LANGSEL", NULL,0, m_langsel);
	state_save_register_item(machine(), "SLTROMSEL", NULL,0, m_sltromsel);
	state_save_register_item(machine(), "CYAREG", NULL,0, m_cyareg);
	state_save_register_item(machine(), "INTEN", NULL,0, m_inten);
	state_save_register_item(machine(), "INTFLAG", NULL,0, m_intflag);
	state_save_register_item(machine(), "SHADOW", NULL,0, m_shadow);
	state_save_register_item(machine(), "PENDIRQ", NULL,0, m_pending_irqs);
	state_save_register_item(machine(), "MX", NULL,0, m_mouse_x);
	state_save_register_item(machine(), "MY", NULL,0, m_mouse_y);
	state_save_register_item(machine(), "MDX", NULL,0, m_mouse_dx);
	state_save_register_item(machine(), "MDY", NULL,0, m_mouse_dy);

	state_save_register_item(machine(), "CLKDATA", NULL,0, m_clock_data);
	state_save_register_item(machine(), "CLKCTRL", NULL,0, m_clock_control);
	state_save_register_item(machine(), "CLKRD", NULL,0, m_clock_read);
	state_save_register_item(machine(), "CLKREG1", NULL,0, m_clock_reg1);
	state_save_register_item(machine(), "CLKCURTIME", NULL,0, m_clock_curtime);
	state_save_register_item(machine(), "CLKCURTIMEINT", NULL,0, m_clock_curtime_interval);
//  state_save_register_item(machine(), "CLKMODE", NULL,0, m_clock_mode);
	save_item(NAME(m_clock_bram));
#if !RUN_ADB_MICRO
	save_item(NAME(m_adb_memory));
	save_item(NAME(m_adb_command_bytes));
	save_item(NAME(m_adb_response_bytes));
//  state_save_register_item(machine(), "ADB", NULL,0, m_adb_state);
	state_save_register_item(machine(), "ADB", NULL,0, m_adb_command);
	state_save_register_item(machine(), "ADB", NULL,0, m_adb_mode);
	state_save_register_item(machine(), "ADB", NULL,0, m_adb_kmstatus);
	state_save_register_item(machine(), "ADB", NULL,0, m_adb_latent_result);
	state_save_register_item(machine(), "ADB", NULL,0, m_adb_command_length);
	state_save_register_item(machine(), "ADB", NULL,0, m_adb_command_pos);
	state_save_register_item(machine(), "ADB", NULL,0, m_adb_response_length);
	state_save_register_item(machine(), "ADB", NULL,0, m_adb_response_pos);
	state_save_register_item(machine(), "ADB", NULL,0, m_adb_address_keyboard);
	state_save_register_item(machine(), "ADB", NULL,0, m_adb_address_mouse);
#endif
	state_save_register_item(machine(), "SNDGLUCTRL", NULL,0, m_sndglu_ctrl);
	state_save_register_item(machine(), "SNDGLUADDR", NULL,0, m_sndglu_addr);
	state_save_register_item(machine(), "SNDGLUDUMMYRD", NULL,0, m_sndglu_dummy_read);

	state_save_register_item(machine(), "ECHOBANK", NULL,0, m_echo_bank);

	m_clock_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(apple2gs_state::apple2gs_clock_tick),this));
	m_clock_timer->adjust(attotime::from_seconds(1), 0, attotime::from_seconds(1));

	m_qsecond_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(apple2gs_state::apple2gs_qsecond_tick),this));
	m_qsecond_timer->adjust(attotime::from_usec(266700), 0, attotime::from_usec(266700));

	m_scanline_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(apple2gs_state::apple2gs_scanline_tick),this));
	m_scanline_timer->adjust(attotime::never);

	// fire on scanline zero
	m_scanline_timer->adjust(machine().first_screen()->time_until_pos(0, 0));
}

MACHINE_START_MEMBER(apple2gs_state,apple2gs)
{
	MACHINE_START_CALL_MEMBER(apple2gscommon);
	apple2gs_setup_memory();
}

MACHINE_START_MEMBER(apple2gs_state,apple2gsr1)
{
	MACHINE_START_CALL_MEMBER(apple2gscommon);

	m_is_rom3 = false;
	apple2gs_setup_memory();
}

void apple2gs_state::apple2gs_refresh_delegates()
{
	write_delegates_2gs0400[0] = write8_delegate(FUNC(apple2gs_state::apple2gs_aux0400_w), this);
	write_delegates_2gs0400[1] = write8_delegate(FUNC(apple2gs_state::apple2gs_main0400_w), this);
	write_delegates_2gs2000[0] = write8_delegate(FUNC(apple2gs_state::apple2gs_aux2000_w), this);
	write_delegates_2gs2000[1] = write8_delegate(FUNC(apple2gs_state::apple2gs_main2000_w), this);
	write_delegates_2gs4000[0] = write8_delegate(FUNC(apple2gs_state::apple2gs_aux4000_w), this);
	write_delegates_2gs4000[1] = write8_delegate(FUNC(apple2gs_state::apple2gs_main4000_w), this);
}

/* -----------------------------------------------------------------------
 * Keym_glu / low-level ADB emulation
 * ----------------------------------------------------------------------- */
#if RUN_ADB_MICRO
UINT8 apple2gs_state::keyglu_mcu_read(UINT8 offset)
{
	UINT8 rv = m_glu_regs[offset];

//  printf("MCU reads reg %x\n", offset);

	// the command full flag is cleared by the MCU reading
	// first the KGS register and then the command register
	if ((offset == GLU_COMMAND) && (m_glu_mcu_read_kgs))
	{
		m_glu_regs[GLU_KG_STATUS] &= ~KGS_COMMAND_FULL;
		m_glu_mcu_read_kgs = false;
//      printf("MCU reads COMMAND = %02x (drop command full)\n", rv);
	}

	// prime for the next command register read to clear the command full flag
	if (offset == GLU_KG_STATUS)
	{
		m_glu_mcu_read_kgs = true;
	}

	return rv;
}

void  apple2gs_state::keyglu_mcu_write(UINT8 offset, UINT8 data)
{
	m_glu_regs[offset] = data;

//  printf("MCU writes %02x to reg %x\n", data, offset);

	switch (offset)
	{
		case GLU_MOUSEX:
		case GLU_MOUSEY:
			m_glu_regs[GLU_KG_STATUS] |= KGS_MOUSEX_FULL;
			m_glu_mouse_read_stat = false;  // signal next read will be mouse X
			break;

		case GLU_ANY_KEY_DOWN:  // bit 7 is the actual flag here; both MCU programs write either 0x7f or 0xff
//          printf("%d to ANY_KEY_DOWN (PC=%x)\n", data, m_adbmicro->pc());
			if (data & 0x80)
			{
				m_glu_regs[GLU_KG_STATUS] |= KGS_ANY_KEY_DOWN | KGS_KEYSTROBE;
			}
			break;

		case GLU_DATA:
			m_glu_regs[GLU_KG_STATUS] |= KGS_DATA_FULL;
			m_glu_816_read_dstat = false;
//          printf("MCU writes %02x to DATA\n", data);
			break;
	}
}

/*
   Keym_glu registers map as follows on the 816:

   C000           = key data + any key down, clears strobe
   C010           = clears keystrobe

   C024 MOUSEDATA = reads GLU mouseX and mouseY
   C025 KEYMODREG = reads GLU keymod register
   C026 DATAREG   = writes from the 816 go to COMMAND, reads from DATA
   C027 KMSTATUS  = GLU system status register

*/
UINT8 apple2gs_state::keyglu_816_read(UINT8 offset)
{
	switch (offset)
	{
		case GLU_C000:
			{
				UINT8 rv;
				rv = m_glu_regs[GLU_KEY_DATA] & 0x7f;
				if (m_glu_regs[GLU_KG_STATUS] & KGS_KEYSTROBE)
				{
					rv |= 0x80;
				}
				return rv;
			}
			break;

		case GLU_C010:
			{
				UINT8 rv;
				rv = m_glu_regs[GLU_KEY_DATA] & 0x7f;
				if (m_glu_regs[GLU_KG_STATUS] & KGS_KEYSTROBE)
				{
					rv |= 0x80;
				}
				m_glu_regs[GLU_KG_STATUS] &= ~KGS_KEYSTROBE;
				return rv;
			}
			break;

		case GLU_MOUSEX:
		case GLU_MOUSEY:
			if (!m_glu_mouse_read_stat)
			{
				m_glu_mouse_read_stat = 1;
				return m_glu_regs[GLU_MOUSEY];
			}
			return m_glu_regs[GLU_MOUSEX];

		case GLU_SYSSTAT:
			// regenerate sysstat bits
			m_glu_sysstat &= ~0xab; // mask off read/write bits
			if (m_glu_regs[GLU_KG_STATUS] & KGS_COMMAND_FULL)
			{
				m_glu_sysstat |= 1;
			}
			if (m_glu_regs[GLU_KG_STATUS] & m_glu_mouse_read_stat)
			{
				m_glu_sysstat |= 2;
			}
			if (m_glu_regs[GLU_KG_STATUS] & KGS_KEYSTROBE)
			{
				m_glu_sysstat |= 8;
			}
			if (m_glu_regs[GLU_KG_STATUS] & KGS_DATA_FULL)
			{
				m_glu_sysstat |= 0x20;
			}
			if (m_glu_regs[GLU_KG_STATUS] & KGS_MOUSEX_FULL)
			{
				m_glu_sysstat |= 0x80;
			}
			m_glu_816_read_dstat = true;
//        printf("816 gets %02x in sysstat (data avail %02x)\n", m_glu_sysstat, m_glu_sysstat & 0x20);
			return m_glu_sysstat;

		case GLU_DATA:
			if (m_glu_816_read_dstat)
			{
				m_glu_816_read_dstat = false;
				m_glu_regs[GLU_KG_STATUS] &= ~KGS_DATA_FULL;
//              printf("816 reads %02x from DATA\n", m_glu_regs[GLU_DATA]);
			}
			return m_glu_regs[GLU_DATA];

		default:
			return m_glu_regs[offset];
			break;
	}

	return 0xff;
}

void  apple2gs_state::keyglu_816_write(UINT8 offset, UINT8 data)
{
	if (offset < GLU_C000)
	{
		m_glu_regs[offset&7] = data;
	}

	switch (offset)
	{
		case GLU_C010:
			m_glu_regs[GLU_KG_STATUS] &= ~KGS_KEYSTROBE;
			break;

		case GLU_COMMAND:
//          printf("816 sets COMMAND to %02x (raise command full)\n", data);
			m_glu_regs[GLU_KG_STATUS] |= KGS_COMMAND_FULL;
			break;

		case GLU_SYSSTAT:
			m_glu_sysstat &= 0xab;  // clear the non-read-only fields
			m_glu_sysstat |= (data & ~0xab);
			break;
	}
}
#endif