summaryrefslogblamecommitdiffstatshomepage
path: root/src/mess/drivers/v1050.c
blob: f6ca3a94d7fcf259dd86df758b730fb451145a95 (plain) (tree)
1
2

                               






























































































                                                                                                     

                       
 
                                                                                                

                                                        
                                                         
 
                                                                                
 

                                                   
 
                                                             
 
              
 
                        
                                             
                                
 
                                                                                                   
 
             
 




                                                 
 
                                             
 
                                
                                 
 




                                                                                  



  

         
                        


                                                                              



                           
                            
















                                                      
                                                              




                                        
                                                                        



                                                  

                                                                   






                                               
                                                        


            

                                                                        

























                                                                   
                      













                                                                   
                      













                                                                   
                              






























































                                                                                                                                                   
                                                              
 
                        












                                        
                                                  



















































                                                
                                                              

 

                                         
                           
 
                               
         
                                                    


         
                                               
 




                                          
         
                                                    


            
                                          


         
                                                        
 
                                

 
                                                        
 
                                





                                         
                               
 







                       
 
          
 
                                           



                                         
                                        






                                                              
                                        


























                                                                                                     
                                                                               




                                                                                       

                                                                                                        

















































































































































                                                                                                                                             
                                         


                                 
                                                                        


         

                          
                                         
 

                                        

 
                                          
 

                                        

 





                                           
                                           
 







                                                     
 
          
 
                              







                                                            

                             
                                               

                       
                                                

                         
                                    

 
                                                     
 





                                                       

 
                                        


          
                                           
 







                                                       
 
          

                       
 

                                         



                    






























                                                                   



                                           
                                           
 







                                                       
 
          

                         
                                                 


                                   
                     

                      
                                         

 





                                          
                                           
 







                                                     
 
          



                          












                                          



                                         
                                           
 







                                          
 
          
 
                            





                                          
                                           
 







                                                   
 
          






                                             

                           
                                                    
 

                                    






                                            

                         
                                               
 

                                     





                                             
                                                      





                                             
                                                      

 

                   
                              


                        

                                                                                                



                                             
                                                                      


         
                                             

                                                                        

                  
                                             





                          
                                           
 


                          

 
  
                                           





                                                                                                                              
                         
  
 

                         
                                               
 
                                                  


                                                                   
                                                               





                                 
                                                              
 






                           
                               
                                      


                                                                
                                                            
 
                                                                


                                                                         
                                                                

                                                                         
                                                                

                                                                         
                                                                







                                                                   

                                   






                                    

                                             




                                 

                     
                        

                       





                                                 


                                                

                                                                  

                                         

                                                        


                                           
                                                                                                           
 
                         


                                      

                                                                  







                                                                          



















                                                                                       




                                                                                             


                                                                               














                                                                                                


                                                                          
                                                   

                                                                       



                                                                                                                   
 
                   











                                                                                                              
 

                                                                        
 
                         

                                                         

                  
                                                                           

                                                                                       
 

                                                                       

















                                                                                                                        
                                                                                                                                                                                                               
// license:BSD-3-Clause
// copyright-holders:Curt Coder
/*

Visual 1050

PCB Layout
----------

REV B-1

|---------------------------------------------------------------------------------------------------|
|                                                               |----------|                        |
|           9216                                                |   ROM0   |        LS74            |
|                                                               |----------|                        |
--                      LS00    7406            LS255   LS393                       4164    4164    |
||      |-----------|                                           |----------|                        |
||      |   WD1793  |   LS14    7407    -       LS393   LS74    |  8251A   |        4164    4164    |
||      |-----------|                   |                       |----------|                        |
|C                                      |                                           4164    4164    |
|N      7406    LS00    LS74    LS14    |C      LS20    LS08    LS75                                |
|1                                      |N                                          4164    4164    |
||                                      |5                                                          |
||      7406    LS195           LS244   |       LS04    LS32    LS08                4164    4164    |
||                                      -                                                           |
||      |------------|  |--------|                                                  4164    4164    |
-- BAT  |   8255A    |  |  8214  |              LS139   LS32    LS138   LS17                        |
--      |------------|  |--------|      -                                           4164    4164    |
||                                      |C                                                          |
||      |--------|      LS00    LS00    |N      LS00    LS32    LS138               4164    4164    |
|C      | 8251A  |                      |6                                                          |
|N      |--------|      |------------|  -                       |------------|                      |
|2                      |   8255A    |                          |    Z80A    |                      |
||      1488 1489  RTC  |------------|          LS00    LS32    |------------|      LS257   LS257   |
||                                                                                                  |
--                                                              |------------|      |------------|  |
|                                                       LS04    |   8255A    |      |   8255A    |  |
|                                                               |------------|      |------------|  |
|                                                                                                   |
|                                               7404                                LS257   LS257   |
|                                                   16MHz                                           |
|       LS04    LS74    LS257                                                       9016    9016    |
|                                                                                                   |
--      LS74    LS04    LS74    LS163                                               9016    9016    |
||                                                                                                  |
||                                                                                  9016    9016    |
||      LS02    LS163   LS74    7404                            7404                                |
||                                                                                  9016    9016    |
||                                                                                                  |
|C      LS244   LS10    LS257                   LS362           |----------|        9016    9016    |
|N                                                              |   ROM1   |                        |
|3      LS245   7404    LS273                   LS32            |----------|        9016    9016    |
||                                                                                                  |
||      7407            LS174                   LS32                                9016    9016    |
||              15.36MHz                                                                            |
||                                                              |------------|      9016    9016    |
--                      LS09    LS04            LS12            |    6502    |                      |
|                                                               |------------|      9016    9016    |
--                                                                                                  |
|C              LS175   LS86    LS164           LS164                               9016    9016    |
|N                                                              |------------|                      |
|4                                                              |    6845    |      LS253   LS253   |
--      7426    LS02    LS74    LS00            LS164           |------------|                      |
|                                                                                   LS253   LS253   |
|                       REV B-1 W/O 1059            S/N 492                                         |
|---------------------------------------------------------------------------------------------------|

Notes:
    All IC's shown.

    ROM0    - "IC 244-032 V1.0"
    ROM1    - "IC 244-033 V1.0"
    Z80A    - Zilog Z8400APS Z80A CPU
    6502    - Synertek SY6502A CPU
    4164    - NEC D4164-2 64Kx1 Dynamic RAM
    9016    - AMD AM9016EPC 16Kx1 Dynamic RAM
    8214    - NEC uPB8214C Priority Interrupt Control Unit
    8255A   - NEC D8255AC-5 Programmable Peripheral Interface
    8251A   - NEC D8251AC Programmable Communication Interface
    WD1793  - Mitsubishi MB8877 Floppy Disc Controller
    9216    - SMC FDC9216 Floppy Disk Data Separator
    1488    - Motorola MC1488 Quad Line EIA-232D Driver
    1489    - Motorola MC1489 Quad Line Receivers
    6845    - Hitachi HD46505SP CRT Controller
    RTC     - OKI MSM58321RS Real Time Clock
    BAT     - 3.4V battery
    CN1     - parallel connector
    CN2     - serial connector
    CN3     - winchester connector
    CN4     - monitor connector
    CN5     - floppy data connector
    CN6     - floppy power connector

*/

/*

    Using the hard disk
    -------------------

    Use the chdman utility to create a Tandon TM501 (5MB) or CMI CM-5412 (10MB) hard disk image:

    $ chdman createhd -chs 306,2,32 -ss 256 -o tm501.chd
    $ chdman createhd -chs 306,4,32 -ss 256 -o cm5412.chd

    Start the Visual 1050 emulator with the floppy and hard disk images mounted:

    $ mess v1050 -flop1 cpm3:flop2 -hard tm501.chd
    $ mess v1050 -flop1 cpm3:flop2 -hard cm5412.chd

    Start the Winchester Format Program from the CP/M prompt:

    A>fmtwinch

    Enter Y to continue.
    Enter A for 5MB, or B for 10MB hard disk.
    Enter C to start formatting.

    Once the formatting is complete, the CP/M system files need to be copied over to the hard disk:

    A>copysys

    Enter source drive name "a" and press RETURN.
    Enter target drive name "c" and press RETURN.
    Enter "y" at the prompt for CPM3.SYS.
    Enter "y" at the prompt for CCP.COM.
    Press RETURN to return to CP/M.

    You can now boot from the hard disk with:

    $ mess v1050 -hard tm501.chd
    $ mess v1050 -hard cm5412.chd

    Or skip all of the above and use the preformatted images in the software list:

    $ mess v1050 -hard cpm3hd5
    $ mess v1050 -hard cpm3hd10

*/

/*

    TODO:

    - floppy 1 is broken
    - write to banked RAM at 0x0000-0x1fff when ROM is active
    - real keyboard w/i8049
    - keyboard beeper (NE555 wired in strange mix of astable/monostable modes)

*/

#include "includes/v1050.h"
#include "bus/rs232/rs232.h"

void v1050_state::set_interrupt(UINT8 mask, int state)
{
	if (state)
	{
		m_int_state |= mask;
	}
	else
	{
		m_int_state &= ~mask;
	}

	m_pic->r_w(~(m_int_state & m_int_mask));
}

void v1050_state::bankswitch()
{
	address_space &program = m_maincpu->space(AS_PROGRAM);

	int bank = (m_bank >> 1) & 0x03;

	if (BIT(m_bank, 0))
	{
		program.install_readwrite_bank(0x0000, 0x1fff, "bank1");
		membank("bank1")->set_entry(bank);
	}
	else
	{
		program.install_read_bank(0x0000, 0x1fff, "bank1");
		program.unmap_write(0x0000, 0x1fff);
		membank("bank1")->set_entry(3);
	}

	membank("bank2")->set_entry(bank);

	if (bank == 2)
	{
		program.unmap_readwrite(0x4000, 0xbfff);
	}
	else
	{
		program.install_readwrite_bank(0x4000, 0x7fff, "bank3");
		program.install_readwrite_bank(0x8000, 0xbfff, "bank4");
		membank("bank3")->set_entry(bank);
		membank("bank4")->set_entry(bank);
	}

	membank("bank5")->set_entry(bank);
}

// Keyboard HACK

static const UINT8 V1050_KEYCODES[4][12][8] =
{
	{   // unshifted
		{ 0xc0, 0xd4, 0xd8, 0xdc, 0xe0, 0xe4, 0xe8, 0xec },
		{ 0xf0, 0xfc, 0x90, 0xf4, 0xf8, 0x94, 0xc4, 0xc8 },
		{ 0xcc, 0xd0, 0x1b, 0x31, 0x32, 0x33, 0x34, 0x35 },
		{ 0x36, 0x37, 0x38, 0x39, 0x30, 0x2d, 0x3d, 0x60 },
		{ 0x08, 0x88, 0x8c, 0x71, 0x77, 0x65, 0x72, 0x74 },
		{ 0x79, 0x75, 0x69, 0x6f, 0x70, 0x5b, 0x5d, 0x0d },
		{ 0x7f, 0x00, 0x80, 0x61, 0x73, 0x64, 0x66, 0x67 },
		{ 0x68, 0x6a, 0x6b, 0x6c, 0x3b, 0x27, 0x5c, 0x84 },
		{ 0x00, 0x7a, 0x78, 0x63, 0x76, 0x62, 0x6e, 0x6d },
		{ 0x2c, 0x2e, 0x2f, 0x00, 0x0a, 0x20, 0x81, 0x82 },
		{ 0xb7, 0xb8, 0xb9, 0xad, 0xb4, 0xb5, 0xb6, 0xac },
		{ 0xb1, 0xb2, 0xb3, 0x83, 0xb0, 0xae, 0x00, 0x00 },
	},

	{   // shifted
		{ 0xc1, 0xd5, 0xd9, 0xdd, 0xe1, 0xe5, 0xe9, 0xed },
		{ 0xf1, 0xfd, 0x91, 0xf5, 0xf9, 0x95, 0xc5, 0xc9 },
		{ 0xcd, 0xd1, 0x1b, 0x21, 0x40, 0x23, 0x24, 0x25 },
		{ 0x5e, 0x26, 0x2a, 0x28, 0x29, 0x5f, 0x2b, 0x7e },
		{ 0x08, 0x89, 0x8d, 0x51, 0x57, 0x45, 0x52, 0x54 },
		{ 0x59, 0x55, 0x49, 0x4f, 0x50, 0x7b, 0x7d, 0x0d },
		{ 0x7f, 0x00, 0x80, 0x41, 0x53, 0x44, 0x46, 0x47 },
		{ 0x48, 0x4a, 0x4b, 0x4c, 0x3a, 0x22, 0x7c, 0x85 },
		{ 0x00, 0x5a, 0x58, 0x43, 0x56, 0x42, 0x4e, 0x4d },
		{ 0x3c, 0x3e, 0x3f, 0x0a, 0x20, 0x81, 0x82, 0xb7 },
		{ 0xb8, 0xb9, 0xad, 0xb4, 0xb5, 0xb6, 0xac, 0xb1 },
		{ 0xb2, 0xb3, 0x83, 0xb0, 0xa0, 0x00, 0x00, 0x00 },
	},

	{   // control
		{ 0xc2, 0xd6, 0xda, 0xde, 0xe2, 0xe6, 0xea, 0xee },
		{ 0xf2, 0xfe, 0x92, 0xf6, 0xfa, 0x96, 0xc6, 0xca },
		{ 0xce, 0xd2, 0x1b, 0x31, 0x32, 0x33, 0x34, 0x35 },
		{ 0x36, 0x37, 0x38, 0x39, 0x30, 0x2d, 0x3d, 0x00 },
		{ 0x08, 0x8a, 0x8e, 0x11, 0x17, 0x05, 0x12, 0x14 },
		{ 0x19, 0x15, 0x09, 0x0f, 0x10, 0x1b, 0x1d, 0x0d },
		{ 0x7f, 0x00, 0x80, 0x01, 0x13, 0x04, 0x06, 0x07 },
		{ 0x08, 0x0a, 0x0b, 0x0c, 0x3b, 0x27, 0x1c, 0x86 },
		{ 0x00, 0x1a, 0x18, 0x03, 0x16, 0x02, 0x0e, 0x0d },
		{ 0x2c, 0x2e, 0x2f, 0x0a, 0x20, 0x81, 0x82, 0xb7 },
		{ 0xb8, 0xb9, 0xad, 0xb4, 0xb5, 0xb6, 0xac, 0xb1 },
		{ 0xb2, 0xb3, 0x83, 0xb0, 0xae, 0x00, 0x00, 0x00 },
	},

	{   // shift & control
		{ 0xc3, 0xd7, 0xdb, 0xdf, 0xe3, 0xe7, 0xeb, 0xef },
		{ 0xf3, 0xff, 0x93, 0xf7, 0xfb, 0x97, 0xc7, 0xcb },
		{ 0xcf, 0xd3, 0x1b, 0x21, 0x00, 0x23, 0x24, 0x25 },
		{ 0x1e, 0x26, 0x2a, 0x28, 0x29, 0x1f, 0x2b, 0x1e },
		{ 0x08, 0x8b, 0x8f, 0x11, 0x17, 0x05, 0x12, 0x14 },
		{ 0x19, 0x15, 0x09, 0x0f, 0x10, 0x1b, 0x1d, 0x0d },
		{ 0x7f, 0x00, 0x80, 0x01, 0x13, 0x04, 0x06, 0x07 },
		{ 0x08, 0x0a, 0x0b, 0x0c, 0x3a, 0x22, 0x1c, 0x87 },
		{ 0x00, 0x1a, 0x18, 0x03, 0x16, 0x02, 0x0e, 0x0d },
		{ 0x3c, 0x3e, 0x3f, 0x0a, 0x20, 0x81, 0x82, 0xb7 },
		{ 0xb8, 0xb9, 0xad, 0xb4, 0xb5, 0xb6, 0xac, 0xb1 },
		{ 0xb2, 0xb3, 0x83, 0xb0, 0xae, 0x00, 0x00, 0x00 },
	}
};

void v1050_state::scan_keyboard()
{
	static const char *const keynames[] = { "ROW0", "ROW1", "ROW2", "ROW3", "ROW4", "ROW5", "ROW6", "ROW7", "ROW8", "ROW9", "ROW10", "ROW11" };
	int table = 0, row, col;
	int keydata = 0xff;

	UINT8 line_mod = ioport("ROW12")->read();

	if((line_mod & 0x07) && (line_mod & 0x18))
	{
		table = 3;  // shift & control
	}
	else if (line_mod & 0x07)
	{
		table = 1; // shifted
	}
	else if (line_mod & 0x18)
	{
		table = 2; // ctrl
	}

	// scan keyboard
	for (row = 0; row < 12; row++)
	{
		UINT8 data = ioport(keynames[row])->read();

		for (col = 0; col < 8; col++)
		{
			if (!BIT(data, col))
			{
				// latch key data
				keydata = V1050_KEYCODES[table][row][col];

				if (m_keydata != keydata)
				{
					m_keydata = keydata;
					m_keyavail = 1;

					set_interrupt(INT_KEYBOARD, 1);
					return;
				}
			}
		}
	}

	m_keydata = keydata;
}

TIMER_DEVICE_CALLBACK_MEMBER(v1050_state::v1050_keyboard_tick)
{
	scan_keyboard();
}

READ8_MEMBER( v1050_state::kb_data_r )
{
	m_keyavail = 0;

	set_interrupt(INT_KEYBOARD, 0);

	return m_keydata;
}

READ8_MEMBER( v1050_state::kb_status_r )
{
	UINT8 val = m_uart_kb->status_r(space, 0);

	return val | (m_keyavail ? 0x02 : 0x00);
}

// Z80 Read/Write Handlers

WRITE8_MEMBER( v1050_state::v1050_i8214_w )
{
	m_pic->b_w((data >> 1) & 0x07);
	m_pic->sgs_w(BIT(data, 4));
}

READ8_MEMBER( v1050_state::vint_clr_r )
{
	set_interrupt(INT_VSYNC, 0);

	return 0xff;
}

WRITE8_MEMBER( v1050_state::vint_clr_w )
{
	set_interrupt(INT_VSYNC, 0);
}

READ8_MEMBER( v1050_state::dint_clr_r )
{
	set_interrupt(INT_DISPLAY, 0);

	return 0xff;
}

WRITE8_MEMBER( v1050_state::dint_clr_w )
{
	set_interrupt(INT_DISPLAY, 0);
}

WRITE8_MEMBER( v1050_state::bank_w )
{
	m_bank = data;

	bankswitch();
}

// SY6502A Read/Write Handlers

WRITE8_MEMBER( v1050_state::dint_w )
{
	set_interrupt(INT_DISPLAY, 1);
}

WRITE8_MEMBER( v1050_state::dvint_clr_w )
{
	m_subcpu->set_input_line(INPUT_LINE_IRQ0, CLEAR_LINE);
}

WRITE8_MEMBER( v1050_state::sasi_data_w )
{
	m_sasi_data = data;

	if (m_sasi_data_enable)
	{
		m_sasi_data_out->write(m_sasi_data);
	}
}

WRITE_LINE_MEMBER( v1050_state::write_sasi_io )
{
	m_sasi_ctrl_in->write_bit4(state);

	m_sasi_data_enable = state;

	if (m_sasi_data_enable)
	{
		m_sasi_data_out->write(m_sasi_data);
	}
	else
	{
		m_sasi_data_out->write(0);
	}
}

TIMER_DEVICE_CALLBACK_MEMBER(v1050_state::sasi_ack_tick)
{
	m_sasibus->write_ack(0);
}

TIMER_DEVICE_CALLBACK_MEMBER(v1050_state::sasi_rst_tick)
{
	m_sasibus->write_rst(0);
}

WRITE8_MEMBER( v1050_state::sasi_ctrl_w )
{
	/*

	    bit     description

	    0       SEL
	    1       ACK
	    2
	    3
	    4
	    5
	    6
	    7       RST

	*/

	m_sasibus->write_sel(BIT(data, 0));

	if (BIT(data, 1))
	{
		// send acknowledge pulse
		m_sasibus->write_ack(1);

		m_timer_ack->adjust(attotime::from_nsec(100));
	}

	if (BIT(data, 7))
	{
		// send reset pulse
		m_sasibus->write_rst(1);

		m_timer_rst->adjust(attotime::from_nsec(100));
	}
}

// Memory Maps

static ADDRESS_MAP_START( v1050_mem, AS_PROGRAM, 8, v1050_state )
	ADDRESS_MAP_UNMAP_HIGH
	AM_RANGE(0x0000, 0x1fff) AM_RAMBANK("bank1")
	AM_RANGE(0x2000, 0x3fff) AM_RAMBANK("bank2")
	AM_RANGE(0x4000, 0x7fff) AM_RAMBANK("bank3")
	AM_RANGE(0x8000, 0xbfff) AM_RAMBANK("bank4")
	AM_RANGE(0xc000, 0xffff) AM_RAMBANK("bank5")
ADDRESS_MAP_END

static ADDRESS_MAP_START( v1050_io, AS_IO, 8, v1050_state )
	ADDRESS_MAP_UNMAP_HIGH
	ADDRESS_MAP_GLOBAL_MASK(0xff)
	AM_RANGE(0x84, 0x87) AM_DEVREADWRITE(I8255A_DISP_TAG, i8255_device, read, write)
//  AM_RANGE(0x88, 0x88) AM_DEVREADWRITE(I8251A_KB_TAG, i8251_device, data_r, data_w)
//  AM_RANGE(0x89, 0x89) AM_DEVREADWRITE(I8251A_KB_TAG, i8251_device, status_r, control_w)
	AM_RANGE(0x88, 0x88) AM_READ(kb_data_r) AM_DEVWRITE(I8251A_KB_TAG, i8251_device, data_w)
	AM_RANGE(0x89, 0x89) AM_READ(kb_status_r) AM_DEVWRITE(I8251A_KB_TAG, i8251_device, control_w)
	AM_RANGE(0x8c, 0x8c) AM_DEVREADWRITE(I8251A_SIO_TAG, i8251_device, data_r, data_w)
	AM_RANGE(0x8d, 0x8d) AM_DEVREADWRITE(I8251A_SIO_TAG, i8251_device, status_r, control_w)
	AM_RANGE(0x90, 0x93) AM_DEVREADWRITE(I8255A_MISC_TAG, i8255_device, read, write)
	AM_RANGE(0x94, 0x97) AM_DEVREADWRITE(MB8877_TAG, mb8877_t, read, write)
	AM_RANGE(0x9c, 0x9f) AM_DEVREADWRITE(I8255A_RTC_TAG, i8255_device, read, write)
	AM_RANGE(0xa0, 0xa0) AM_READWRITE(vint_clr_r, vint_clr_w)
	AM_RANGE(0xb0, 0xb0) AM_READWRITE(dint_clr_r, dint_clr_w)
	AM_RANGE(0xc0, 0xc0) AM_WRITE(v1050_i8214_w)
	AM_RANGE(0xd0, 0xd0) AM_WRITE(bank_w)
	AM_RANGE(0xe0, 0xe0) AM_WRITE(sasi_data_w) AM_DEVREAD("scsi_data_in", input_buffer_device, read)
	AM_RANGE(0xe1, 0xe1) AM_DEVREAD("scsi_ctrl_in", input_buffer_device, read) AM_WRITE(sasi_ctrl_w)
ADDRESS_MAP_END

static ADDRESS_MAP_START( v1050_crt_mem, AS_PROGRAM, 8, v1050_state )
	AM_RANGE(0x0000, 0x7fff) AM_READWRITE(videoram_r, videoram_w) AM_SHARE("video_ram")
	AM_RANGE(0x8000, 0x8000) AM_DEVWRITE(H46505_TAG, mc6845_device, address_w)
	AM_RANGE(0x8001, 0x8001) AM_DEVREADWRITE(H46505_TAG, mc6845_device, register_r, register_w)
	AM_RANGE(0x9000, 0x9003) AM_DEVREADWRITE(I8255A_M6502_TAG, i8255_device, read, write)
	AM_RANGE(0xa000, 0xa000) AM_READWRITE(attr_r, attr_w)
	AM_RANGE(0xb000, 0xb000) AM_WRITE(dint_w)
	AM_RANGE(0xc000, 0xc000) AM_WRITE(dvint_clr_w)
	AM_RANGE(0xe000, 0xffff) AM_ROM
ADDRESS_MAP_END

// Input Ports

static INPUT_PORTS_START( v1050 )
	PORT_START("ROW0")
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) // HELP
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F1)
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F2)
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F3)
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F4)
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F5)
	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F6)
	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F7)

	PORT_START("ROW1")
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F8)
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F9)
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F10)
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F11)
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F12)
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F13)
	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F14)
	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F15)

	PORT_START("ROW2")
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) // F16
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) // F17
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("ESC") PORT_CODE(KEYCODE_ESC) PORT_CHAR(UCHAR_MAMEKEY(ESC))
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!')
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('@')
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#')
	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$')
	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%')

	PORT_START("ROW3")
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('^')
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('&')
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('*')
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR('(')
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHAR(')')
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('_')
	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('=') PORT_CHAR('+')
	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_TILDE) PORT_CHAR('`') PORT_CHAR('~')

	PORT_START("ROW4")
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("BACKSPACE") PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8)
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("BREAK") PORT_CODE(KEYCODE_PAUSE)
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("TAB") PORT_CODE(KEYCODE_TAB) PORT_CHAR('\t')
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Q) PORT_CHAR('q') PORT_CHAR('Q')
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_W) PORT_CHAR('w') PORT_CHAR('W')
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_E) PORT_CHAR('e') PORT_CHAR('E')
	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_R) PORT_CHAR('r') PORT_CHAR('R')
	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_T) PORT_CHAR('t') PORT_CHAR('T')

	PORT_START("ROW5")
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Y) PORT_CHAR('y') PORT_CHAR('Y')
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_U) PORT_CHAR('u') PORT_CHAR('U')
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_I) PORT_CHAR('i') PORT_CHAR('I')
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_O) PORT_CHAR('o') PORT_CHAR('O')
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_P) PORT_CHAR('p') PORT_CHAR('P')
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('[') PORT_CHAR('{')
	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR(']') PORT_CHAR('}')
	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("RETURN") PORT_CODE(KEYCODE_ENTER) PORT_CHAR('\r')

	PORT_START("ROW6")
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("DEL") PORT_CODE(KEYCODE_DEL)
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD )
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD )
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_A) PORT_CHAR('a') PORT_CHAR('A')
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_S) PORT_CHAR('s') PORT_CHAR('S')
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_D) PORT_CHAR('d') PORT_CHAR('D')
	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F) PORT_CHAR('f') PORT_CHAR('F')
	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_G) PORT_CHAR('g') PORT_CHAR('G')

	PORT_START("ROW7")
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_H) PORT_CHAR('h') PORT_CHAR('H')
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_J) PORT_CHAR('j') PORT_CHAR('J')
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_K) PORT_CHAR('k') PORT_CHAR('K')
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_L) PORT_CHAR('l') PORT_CHAR('L')
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR(':')
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR('\'') PORT_CHAR('"')
	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR('\\') PORT_CHAR('|')
	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_SCRLOCK)

	PORT_START("ROW8")
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) // SHIFT
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Z) PORT_CHAR('z') PORT_CHAR('Z')
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_X) PORT_CHAR('x') PORT_CHAR('X')
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_C) PORT_CHAR('c') PORT_CHAR('C')
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_V) PORT_CHAR('v') PORT_CHAR('V')
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_B) PORT_CHAR('b') PORT_CHAR('B')
	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_N) PORT_CHAR('n') PORT_CHAR('N')
	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_M) PORT_CHAR('m') PORT_CHAR('M')

	PORT_START("ROW9")
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<')
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>')
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?')
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) // SHIFT
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("LINE FEED") PORT_CODE(KEYCODE_ENTER_PAD)
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_SPACE)
	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_NUMLOCK) // DOWN
	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_NUMLOCK) // UP

	PORT_START("ROW10")
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Keypad 7") PORT_CODE(KEYCODE_7_PAD)
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Keypad 8") PORT_CODE(KEYCODE_8_PAD)
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Keypad 9") PORT_CODE(KEYCODE_9_PAD)
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Keypad -") PORT_CODE(KEYCODE_MINUS_PAD)
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Keypad 4") PORT_CODE(KEYCODE_4_PAD)
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Keypad 5") PORT_CODE(KEYCODE_5_PAD)
	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Keypad 6") PORT_CODE(KEYCODE_6_PAD)
	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME(UTF8_UP) PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP))

	PORT_START("ROW11")
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Keypad 1") PORT_CODE(KEYCODE_1_PAD)
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Keypad 2") PORT_CODE(KEYCODE_2_PAD)
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Keypad 3") PORT_CODE(KEYCODE_3_PAD)
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Keypad 0") PORT_CODE(KEYCODE_0_PAD)
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("Keypad +") PORT_CODE(KEYCODE_PLUS_PAD)
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD )
	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD )
	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD )

	PORT_START("ROW12")
	PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("LOCK") PORT_CODE(KEYCODE_CAPSLOCK) PORT_TOGGLE
	PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("LEFT SHIFT") PORT_CODE(KEYCODE_LSHIFT) PORT_CHAR(UCHAR_SHIFT_1)
	PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("RIGHT SHIFT") PORT_CODE(KEYCODE_RSHIFT)
	PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("LEFT CTRL") PORT_CODE(KEYCODE_LCONTROL) PORT_CHAR(UCHAR_MAMEKEY(LCONTROL))
	PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("RIGHT CTRL") PORT_CODE(KEYCODE_RCONTROL) PORT_CHAR(UCHAR_MAMEKEY(RCONTROL))
INPUT_PORTS_END

// 8214 Interface

WRITE_LINE_MEMBER(v1050_state::pic_int_w)
{
	if (state == ASSERT_LINE)
	{
		m_maincpu->set_input_line(INPUT_LINE_IRQ0, ASSERT_LINE);
	}
}

// Display 8255A Interface

WRITE8_MEMBER(v1050_state::disp_ppi_pc_w)
{
	m_ppi_6502->pc2_w(BIT(data, 6));
	m_ppi_6502->pc4_w(BIT(data, 7));
}

WRITE8_MEMBER(v1050_state::m6502_ppi_pc_w)
{
	m_ppi_disp->pc2_w(BIT(data, 7));
	m_ppi_disp->pc4_w(BIT(data, 6));
}

// Miscellanous 8255A Interface

WRITE8_MEMBER( v1050_state::misc_ppi_pa_w )
{
	/*

	    bit     signal      description

	    PA0     f_ds<0>     drive 0 select
	    PA1     f_ds<1>     drive 1 select
	    PA2     f_ds<2>     drive 2 select
	    PA3     f_ds<3>     drive 3 select
	    PA4     f_side_1    floppy side select
	    PA5     f_pre_comp  precompensation
	    PA6     f_motor_on* floppy motor
	    PA7     f_dden*     double density select

	*/

	// floppy drive select
	floppy_image_device *floppy = NULL;

	if (!BIT(data, 0)) floppy = m_floppy0->get_device();
	if (!BIT(data, 1)) floppy = m_floppy1->get_device();
	if (!BIT(data, 2)) floppy = m_floppy2->get_device();
	if (!BIT(data, 3)) floppy = m_floppy3->get_device();

	m_fdc->set_floppy(floppy);

	// floppy side select
	if (floppy) floppy->ss_w(BIT(data, 4));

	// floppy motor
	if (floppy) floppy->mon_w(BIT(data, 6));

	// density select
	m_fdc->dden_w(BIT(data, 7));
}

WRITE_LINE_MEMBER(v1050_state::write_centronics_busy)
{
	m_centronics_busy = state;
}

WRITE_LINE_MEMBER(v1050_state::write_centronics_perror)
{
	m_centronics_perror = state;
}

READ8_MEMBER(v1050_state::misc_ppi_pc_r)
{
	/*

	    bit     signal      description

	    PC0     pr_strobe   printer strobe
	    PC1     f_int_enb   floppy interrupt enable
	    PC2     baud_sel_a
	    PC3     baud_sel_b
	    PC4     pr_busy*    printer busy
	    PC5     pr_pe*      printer paper end
	    PC6
	    PC7

	*/

	UINT8 data = 0;

	data |= m_centronics_busy << 4;
	data |= m_centronics_perror << 5;

	return data;
}

void v1050_state::set_baud_sel(int baud_sel)
{
	if (baud_sel != m_baud_sel)
	{
		int divider = 1;

		switch (baud_sel)
		{
		case 0:
			divider = 13 * 16; // 19200
			break;

		case 1:
			divider = 13 * 8; // 38400
			break;

		case 2:
			divider = 8; // 500000
			break;

		case 3:
			divider = 13 * 2; // 153600
			break;
		}

		m_clock_sio->set_clock_scale((double) 1 / divider);

		m_baud_sel = baud_sel;
	}
}

WRITE8_MEMBER( v1050_state::misc_ppi_pc_w )
{
	/*

	    bit     signal      description

	    PC0     pr_strobe   printer strobe
	    PC1     f_int_enb   floppy interrupt enable
	    PC2     baud_sel_a
	    PC3     baud_sel_b
	    PC4     pr_busy*    printer busy
	    PC5     pr_pe*      printer paper end
	    PC6
	    PC7

	*/

	// printer strobe
	m_centronics->write_strobe(BIT(data, 0));

	// floppy interrupt enable
	m_f_int_enb = BIT(data, 1);
	update_fdc();

	// baud select
	set_baud_sel((data >> 2) & 0x03);
}

// Real Time Clock 8255A Interface

WRITE8_MEMBER( v1050_state::rtc_ppi_pb_w )
{
	/*

	    bit     signal      description

	    PB0                 RS-232
	    PB1                 Winchester
	    PB2                 keyboard
	    PB3                 floppy disk interrupt
	    PB4                 vertical interrupt
	    PB5                 display interrupt
	    PB6                 expansion B
	    PB7                 expansion A

	*/

	m_int_mask = data;
}

READ8_MEMBER( v1050_state::rtc_ppi_pa_r )
{
	return m_rtc_ppi_pa;
}

WRITE8_MEMBER( v1050_state::rtc_ppi_pa_w )
{
	m_rtc->d0_w((data >> 0) & 1);
	m_rtc->d1_w((data >> 1) & 1);
	m_rtc->d2_w((data >> 2) & 1);
	m_rtc->d3_w((data >> 3) & 1);
}

READ8_MEMBER( v1050_state::rtc_ppi_pc_r )
{
	/*

	    bit     signal      description

	    PC0
	    PC1
	    PC2
	    PC3                 clock busy
	    PC4
	    PC5
	    PC6
	    PC7

	*/

	return m_rtc_ppi_pc;
}

WRITE8_MEMBER( v1050_state::rtc_ppi_pc_w )
{
	/*

	    bit     signal      description

	    PC0
	    PC1
	    PC2
	    PC3
	    PC4                 clock address write
	    PC5                 clock data write
	    PC6                 clock data read
	    PC7                 clock device select

	*/

	m_rtc->address_write_w(BIT(data, 4));
	m_rtc->write_w(BIT(data, 5));
	m_rtc->read_w(BIT(data, 6));
	m_rtc->cs2_w(BIT(data, 7));
}

// Keyboard 8251A Interface

WRITE_LINE_MEMBER(v1050_state::write_keyboard_clock)
{
	m_uart_kb->write_txc(state);
	m_uart_kb->write_rxc(state);
}

WRITE_LINE_MEMBER( v1050_state::kb_rxrdy_w )
{
	set_interrupt(INT_KEYBOARD, state);
}

// Serial 8251A Interface

WRITE_LINE_MEMBER(v1050_state::write_sio_clock)
{
	m_uart_sio->write_txc(state);
	m_uart_sio->write_rxc(state);
}

WRITE_LINE_MEMBER( v1050_state::sio_rxrdy_w )
{
	m_rxrdy = state;

	set_interrupt(INT_RS_232, m_rxrdy || m_txrdy);
}

WRITE_LINE_MEMBER( v1050_state::sio_txrdy_w )
{
	m_txrdy = state;

	set_interrupt(INT_RS_232, m_rxrdy || m_txrdy);
}

// MB8877 Interface

void v1050_state::update_fdc()
{
	if (m_f_int_enb)
	{
		set_interrupt(INT_FLOPPY, m_fdc_irq ? 1 : 0);
		m_maincpu->set_input_line(INPUT_LINE_NMI, m_fdc_drq ? ASSERT_LINE : CLEAR_LINE);
	}
	else
	{
		set_interrupt(INT_FLOPPY, 0);
		m_maincpu->set_input_line(INPUT_LINE_NMI, CLEAR_LINE);
	}
}

static SLOT_INTERFACE_START( v1050_floppies )
	SLOT_INTERFACE( "525ssqd", FLOPPY_525_SSQD ) // Teac FD 55E-02-U
	SLOT_INTERFACE( "525qd", FLOPPY_525_QD ) // Teac FD 55-FV-35-U
SLOT_INTERFACE_END

WRITE_LINE_MEMBER( v1050_state::fdc_intrq_w )
{
	m_fdc_irq = state;

	update_fdc();
}

WRITE_LINE_MEMBER( v1050_state::fdc_drq_w )
{
	m_fdc_drq = state;

	update_fdc();
}

/*
static LEGACY_FLOPPY_OPTIONS_START( v1050 )
    LEGACY_FLOPPY_OPTION( v1050, "dsk", "Visual 1050 disk image", basicdsk_identify_default, basicdsk_construct_default, NULL,
        HEADS([1])
        TRACKS([80])
        SECTORS([10])
        SECTOR_LENGTH([512])
        FIRST_SECTOR_ID([1]))
LEGACY_FLOPPY_OPTIONS_END
*/

// Machine Initialization

IRQ_CALLBACK_MEMBER(v1050_state::v1050_int_ack)
{
	UINT8 vector = 0xf0 | (m_pic->a_r() << 1);

	//logerror("Interrupt Acknowledge Vector: %02x\n", vector);

	m_maincpu->set_input_line(INPUT_LINE_IRQ0, CLEAR_LINE);

	return vector;
}

void v1050_state::machine_start()
{
	address_space &program = m_maincpu->space(AS_PROGRAM);

	// initialize I8214
	m_pic->etlg_w(1);
	m_pic->inte_w(1);

	// initialize RTC
	m_rtc->cs1_w(1);

	// setup memory banking
	UINT8 *ram = m_ram->pointer();

	membank("bank1")->configure_entries(0, 2, ram, 0x10000);
	membank("bank1")->configure_entry(2, ram + 0x1c000);
	membank("bank1")->configure_entry(3, m_rom->base());

	program.install_readwrite_bank(0x2000, 0x3fff, "bank2");
	membank("bank2")->configure_entries(0, 2, ram + 0x2000, 0x10000);
	membank("bank2")->configure_entry(2, ram + 0x1e000);

	program.install_readwrite_bank(0x4000, 0x7fff, "bank3");
	membank("bank3")->configure_entries(0, 2, ram + 0x4000, 0x10000);

	program.install_readwrite_bank(0x8000, 0xbfff, "bank4");
	membank("bank4")->configure_entries(0, 2, ram + 0x8000, 0x10000);

	program.install_readwrite_bank(0xc000, 0xffff, "bank5");
	membank("bank5")->configure_entries(0, 3, ram + 0xc000, 0);

	bankswitch();

	// register for state saving
	save_item(NAME(m_int_mask));
	save_item(NAME(m_int_state));
	save_item(NAME(m_f_int_enb));
	save_item(NAME(m_fdc_irq));
	save_item(NAME(m_fdc_drq));
	save_item(NAME(m_keylatch));
	save_item(NAME(m_keydata));
	save_item(NAME(m_keyavail));
	save_item(NAME(m_rxrdy));
	save_item(NAME(m_txrdy));
	save_item(NAME(m_baud_sel));
	save_item(NAME(m_bank));
	save_item(NAME(m_centronics_busy));
	save_item(NAME(m_centronics_perror));
}

void v1050_state::machine_reset()
{
	m_bank = 0;
	bankswitch();

	set_baud_sel(0);

	m_fdc->reset();
}

// Machine Driver

static MACHINE_CONFIG_START( v1050, v1050_state )
	// basic machine hardware
	MCFG_CPU_ADD(Z80_TAG, Z80, XTAL_16MHz/4)
	MCFG_CPU_PROGRAM_MAP(v1050_mem)
	MCFG_CPU_IO_MAP(v1050_io)
	MCFG_CPU_IRQ_ACKNOWLEDGE_DRIVER(v1050_state,v1050_int_ack)

	MCFG_QUANTUM_PERFECT_CPU(Z80_TAG)

	MCFG_CPU_ADD(M6502_TAG, M6502, XTAL_15_36MHz/16)
	MCFG_CPU_PROGRAM_MAP(v1050_crt_mem)
	MCFG_QUANTUM_PERFECT_CPU(M6502_TAG)

	// keyboard HACK
	MCFG_TIMER_DRIVER_ADD_PERIODIC("keyboard", v1050_state, v1050_keyboard_tick, attotime::from_hz(60))

	// video hardware
	MCFG_FRAGMENT_ADD(v1050_video)

	// devices
	MCFG_DEVICE_ADD(UPB8214_TAG, I8214, XTAL_16MHz/4)
	MCFG_I8214_IRQ_CALLBACK(WRITELINE(v1050_state, pic_int_w))

	MCFG_DEVICE_ADD(MSM58321RS_TAG, MSM58321, XTAL_32_768kHz)
	MCFG_MSM58321_D0_HANDLER(WRITELINE(v1050_state, rtc_ppi_pa_0_w))
	MCFG_MSM58321_D1_HANDLER(WRITELINE(v1050_state, rtc_ppi_pa_1_w))
	MCFG_MSM58321_D2_HANDLER(WRITELINE(v1050_state, rtc_ppi_pa_2_w))
	MCFG_MSM58321_D3_HANDLER(WRITELINE(v1050_state, rtc_ppi_pa_3_w))
	MCFG_MSM58321_BUSY_HANDLER(WRITELINE(v1050_state, rtc_ppi_pc_3_w))

	MCFG_DEVICE_ADD(I8255A_DISP_TAG, I8255A, 0)
	MCFG_I8255_IN_PORTA_CB(DEVREAD8(I8255A_M6502_TAG, i8255_device, pb_r))
	MCFG_I8255_OUT_PORTC_CB(WRITE8(v1050_state, disp_ppi_pc_w))

	MCFG_DEVICE_ADD(I8255A_MISC_TAG, I8255A, 0)
	MCFG_I8255_OUT_PORTA_CB(WRITE8(v1050_state, misc_ppi_pa_w))
	MCFG_I8255_OUT_PORTB_CB(DEVWRITE8("cent_data_out", output_latch_device, write))
	MCFG_I8255_IN_PORTC_CB(READ8(v1050_state,misc_ppi_pc_r))
	MCFG_I8255_OUT_PORTC_CB(WRITE8(v1050_state,misc_ppi_pc_w))

	MCFG_DEVICE_ADD(I8255A_RTC_TAG, I8255A, 0)
	MCFG_I8255_IN_PORTA_CB(READ8(v1050_state, rtc_ppi_pa_r))
	MCFG_I8255_OUT_PORTA_CB(WRITE8(v1050_state, rtc_ppi_pa_w))
	MCFG_I8255_OUT_PORTB_CB(WRITE8(v1050_state, rtc_ppi_pb_w))
	MCFG_I8255_IN_PORTC_CB(READ8(v1050_state, rtc_ppi_pc_r))
	MCFG_I8255_OUT_PORTC_CB(WRITE8(v1050_state, rtc_ppi_pc_w))

	MCFG_DEVICE_ADD(I8255A_M6502_TAG, I8255A, 0)
	MCFG_I8255_IN_PORTA_CB(DEVREAD8(I8255A_DISP_TAG, i8255_device, pb_r))
	MCFG_I8255_OUT_PORTC_CB(WRITE8(v1050_state, m6502_ppi_pc_w))

	MCFG_DEVICE_ADD(I8251A_KB_TAG, I8251, 0/*XTAL_16MHz/8,*/)
	MCFG_I8251_TXD_HANDLER(DEVWRITELINE(V1050_KEYBOARD_TAG, v1050_keyboard_device, si_w))
	MCFG_I8251_RXRDY_HANDLER(WRITELINE(v1050_state, kb_rxrdy_w))

	MCFG_DEVICE_ADD(CLOCK_KB_TAG, CLOCK, XTAL_16MHz/4/13/8)
	MCFG_CLOCK_SIGNAL_HANDLER(WRITELINE(v1050_state, write_keyboard_clock))

	// keyboard
	MCFG_DEVICE_ADD(V1050_KEYBOARD_TAG, V1050_KEYBOARD, 0)
	MCFG_V1050_KEYBOARD_OUT_TX_HANDLER(DEVWRITELINE(I8251A_KB_TAG, i8251_device, write_rxd))

	MCFG_DEVICE_ADD(I8251A_SIO_TAG, I8251, 0/*XTAL_16MHz/8,*/)
	MCFG_I8251_TXD_HANDLER(DEVWRITELINE(RS232_TAG, rs232_port_device, write_txd))
	MCFG_I8251_DTR_HANDLER(DEVWRITELINE(RS232_TAG, rs232_port_device, write_dtr))
	MCFG_I8251_RTS_HANDLER(DEVWRITELINE(RS232_TAG, rs232_port_device, write_rts))
	MCFG_I8251_RXRDY_HANDLER(WRITELINE(v1050_state, sio_rxrdy_w))
	MCFG_I8251_TXRDY_HANDLER(WRITELINE(v1050_state, sio_txrdy_w))

	MCFG_RS232_PORT_ADD(RS232_TAG, default_rs232_devices, NULL)
	MCFG_RS232_RXD_HANDLER(DEVWRITELINE(I8251A_SIO_TAG, i8251_device, write_rxd))
	MCFG_RS232_DSR_HANDLER(DEVWRITELINE(I8251A_SIO_TAG, i8251_device, write_dsr))

	MCFG_DEVICE_ADD(CLOCK_SIO_TAG, CLOCK, XTAL_16MHz/4)
	MCFG_CLOCK_SIGNAL_HANDLER(WRITELINE(v1050_state, write_sio_clock))

	MCFG_MB8877x_ADD(MB8877_TAG, XTAL_16MHz/16)
	MCFG_WD_FDC_INTRQ_CALLBACK(WRITELINE(v1050_state, fdc_intrq_w))
	MCFG_WD_FDC_DRQ_CALLBACK(WRITELINE(v1050_state, fdc_drq_w))
	MCFG_FLOPPY_DRIVE_ADD(MB8877_TAG":0", v1050_floppies, "525qd", floppy_image_device::default_floppy_formats)
	MCFG_FLOPPY_DRIVE_ADD(MB8877_TAG":1", v1050_floppies, "525qd", floppy_image_device::default_floppy_formats)
	MCFG_FLOPPY_DRIVE_ADD(MB8877_TAG":2", v1050_floppies, NULL,    floppy_image_device::default_floppy_formats)
	MCFG_FLOPPY_DRIVE_ADD(MB8877_TAG":3", v1050_floppies, NULL,    floppy_image_device::default_floppy_formats)

	// SASI bus
	MCFG_DEVICE_ADD(SASIBUS_TAG, SCSI_PORT, 0)
	MCFG_SCSI_DATA_INPUT_BUFFER("scsi_data_in")
	MCFG_SCSI_REQ_HANDLER(DEVWRITELINE("scsi_ctrl_in", input_buffer_device, write_bit0)) MCFG_DEVCB_XOR(1)
	MCFG_SCSI_BSY_HANDLER(DEVWRITELINE("scsi_ctrl_in", input_buffer_device, write_bit1))
	MCFG_SCSI_MSG_HANDLER(DEVWRITELINE("scsi_ctrl_in", input_buffer_device, write_bit2))
	MCFG_SCSI_CD_HANDLER(DEVWRITELINE("scsi_ctrl_in", input_buffer_device, write_bit3))
	MCFG_SCSI_IO_HANDLER(WRITELINE(v1050_state, write_sasi_io)) MCFG_DEVCB_XOR(1) // bit4
	MCFG_SCSIDEV_ADD(SASIBUS_TAG ":" SCSI_PORT_DEVICE1, "harddisk", S1410, SCSI_ID_0)

	MCFG_SCSI_OUTPUT_LATCH_ADD("scsi_data_out", SASIBUS_TAG)
	MCFG_DEVICE_ADD("scsi_data_in", INPUT_BUFFER, 0)
	MCFG_DEVICE_ADD("scsi_ctrl_in", INPUT_BUFFER, 0)

	MCFG_TIMER_DRIVER_ADD(TIMER_ACK_TAG, v1050_state, sasi_ack_tick)
	MCFG_TIMER_DRIVER_ADD(TIMER_RST_TAG, v1050_state, sasi_rst_tick)

	// software lists
	MCFG_SOFTWARE_LIST_ADD("flop_list", "v1050_flop")
	MCFG_SOFTWARE_LIST_ADD("hdd_list", "v1050_hdd")

	// printer
	MCFG_CENTRONICS_ADD(CENTRONICS_TAG, centronics_printers, "printer")
	MCFG_CENTRONICS_BUSY_HANDLER(WRITELINE(v1050_state, write_centronics_busy))
	MCFG_CENTRONICS_PERROR_HANDLER(WRITELINE(v1050_state, write_centronics_perror))

	MCFG_CENTRONICS_OUTPUT_LATCH_ADD("cent_data_out", "centronics")

	// internal ram
	MCFG_RAM_ADD(RAM_TAG)
	MCFG_RAM_DEFAULT_SIZE("128K")
MACHINE_CONFIG_END

// ROMs

ROM_START( v1050 )
	ROM_REGION( 0x10000, Z80_TAG, 0 )
	ROM_LOAD( "e244-032 rev 1.2.u86", 0x0000, 0x2000, CRC(46f847a7) SHA1(374db7a38a9e9230834ce015006e2f1996b9609a) )

	ROM_REGION( 0x10000, M6502_TAG, 0 )
	ROM_LOAD( "e244-033 rev 1.1.u77", 0xe000, 0x2000, CRC(c0502b66) SHA1(bc0015f5b14f98110e652eef9f7c57c614683be5) )
ROM_END

// System Drivers

//    YEAR  NAME    PARENT  COMPAT  MACHINE INPUT   INIT    COMPANY                     FULLNAME        FLAGS
COMP( 1983, v1050,  0,      0,      v1050,  v1050, driver_device,   0,      "Visual Technology Inc",    "Visual 1050", GAME_IMPERFECT_GRAPHICS | GAME_SUPPORTS_SAVE | GAME_NO_SOUND | GAME_IMPERFECT_KEYBOARD )