summaryrefslogblamecommitdiffstatshomepage
path: root/src/mame/machine/super80.cpp
blob: b09d0c39c41393b5687de5448cd01d3be27343fa (plain) (tree)
1
2
3
4
5
6
7

                             

                                                                                    
                
                             
                           






                                                                                                                 

                                                                                     
 
                                           
 
                            
 




                                                         
 

                          
                    
 
 

                                                                                                                  
                                                              
 




                                                         
                                                                                      
            
                                                                                     

                                               
                                        
                                                                                         
            
                                                                                       




                                                                                                      








                                                                                          
 
                        

                                                                                                       
 

                                                                                                 
 


                                        
                                                      
 
                          
 
                         
                                                          
 
                                      
         
                                                                           
                                         
                                                                                              
                                   
         


                                                                             
                                                   
 
                                      

 
                                                      
 
                            
                                                                                                                                     
                                                                          



                                                                                      
                              
                                                                                                        
 

                                 
                 
                                                                                                           
                                     



                 
                                                                                         
                 
                                                                               
                                                                                    
















                                                                                                           

                                       
                                                                          

 
                                                

                                        
                                                                    
                                   
 
                                              













                                                             

 

                                           
                                                                       

                                                                                                                   





                                                                      


                                               




                                            
                                          
                        
                                                                             
                                                                                             
                                                                                  





                                             
                                          
                               
                                                                             
                                                                                             
                                                                                  





                                                                                                                     
                                              
 
                                                                                         

                          
                            
                                                                                                                                  


                                      
                                               








                                                                                                                                  
                                  
 
                                                    
                                                                       

 

                                                   
                                                   

                                                   
                                               
 
                                                 

                                         

                                                                                                                                             


                                      
                                                   
                                                
                                                     
 
                                       
 
// license:BSD-3-Clause
// copyright-holders:Robbbert
/* Super80.c written by Robbbert, 2005-2009. See driver source for documentation. */

#include "emu.h"
#include "includes/super80.h"
#include "machine/z80bin.h"

/**************************** PIO ******************************************************************************/


WRITE8_MEMBER( super80_state::pio_port_a_w )
{
	m_keylatch = data;
	m_pio->port_b_write(pio_port_b_r(generic_space(),0,0xff)); // refresh kbd int
}

READ8_MEMBER( super80_state::pio_port_b_r )
{
	uint8_t data = 0xff;

	for (int i = 0; i < 8; i++)
	{
		if (!BIT(m_keylatch, i))
			data &= m_io_keyboard[i]->read();
	}

	m_key_pressed = 3;

	return data;
}

/**************************** CASSETTE ROUTINES *****************************************************************/

void super80_state::super80_cassette_motor( bool motor_state )
{
	// relay sound
	if (BIT(m_last_data, 1) != motor_state)
		m_samples->start(0, motor_state ? 0 : 1);

	if (motor_state)
		m_cassette->change_state(CASSETTE_MOTOR_DISABLED,CASSETTE_MASK_MOTOR);
	else
		m_cassette->change_state(CASSETTE_MOTOR_ENABLED,CASSETTE_MASK_MOTOR);

	/* does user want to hear the sound? */
	if (BIT(m_io_config->read(), 3))
		m_cassette->change_state(CASSETTE_SPEAKER_ENABLED,CASSETTE_MASK_SPEAKER);
	else
		m_cassette->change_state(CASSETTE_SPEAKER_MUTED,CASSETTE_MASK_SPEAKER);
}

/********************************************* TIMER ************************************************/


// If normal keyboard scan has stopped, then do a scan to allow the interrupt key sequence
TIMER_DEVICE_CALLBACK_MEMBER( super80_state::timer_k )
{
	if (m_key_pressed)
		m_key_pressed--;
	else
	if (!m_key_pressed)
		m_pio->port_b_write(pio_port_b_r(generic_space(),0,0xff));
}

/* cassette load circuit
    This "emulates" U79 CD4046BCN PLL chip and U1 LM311P op-amp. U79 converts a frequency to a voltage,
    and U1 amplifies that voltage to digital levels. U1 has a trimpot connected, to set the midpoint.

    The MDS homebrew input circuit consists of 2 op-amps followed by a D-flipflop.
    The "read-any-system" cassette circuit is a CA3140 op-amp, the smarts being done in software.

    bit 0 = original system (U79 and U1)
    bit 1 = MDS fast system
    bit 2 = CA3140 */
TIMER_DEVICE_CALLBACK_MEMBER( super80_state::timer_p )
{
	uint8_t cass_ws=0;

	m_cass_data[1]++;
	cass_ws = ((m_cassette)->input() > +0.03) ? 4 : 0;

	if (cass_ws != m_cass_data[0])
	{
		if (cass_ws) m_cass_data[3] ^= 2;       // the MDS flipflop
		m_cass_data[0] = cass_ws;
		m_cass_data[2] = ((m_cass_data[1] < 0x0d) ? 1 : 0) | cass_ws | m_cass_data[3];
		m_cass_data[1] = 0;
	}
}

/* after the first 4 bytes have been read from ROM, switch the ram back in */
TIMER_CALLBACK_MEMBER(super80_state::super80_reset)
{
	membank("boot")->set_entry(0);
}

TIMER_DEVICE_CALLBACK_MEMBER( super80_state::timer_h )
{
	uint8_t go_fast = 0;
	if ( (!BIT(m_portf0, 2)) | (!BIT(m_io_config->read(), 1)) )    /* bit 2 of port F0 is low, OR user turned on config switch */
		go_fast++; // must be 1 at boot so banking works correctly

	/* code to slow down computer to 1 MHz by halting cpu on every second frame */
	if (!go_fast)
	{
		if (!m_int_sw)
			m_maincpu->set_input_line(INPUT_LINE_HALT, ASSERT_LINE);    // if going, stop it

		m_int_sw++;
		if (m_int_sw > 1)
		{
			m_maincpu->set_input_line(INPUT_LINE_HALT, CLEAR_LINE);     // if stopped, start it
			m_int_sw = 0;
		}
	}
	else
	{
		if (m_int_sw < 8)                               // @2MHz, reset just once
		{
			m_maincpu->set_input_line(INPUT_LINE_HALT, CLEAR_LINE);
			m_int_sw = 8;                           // ...not every time
		}
	}
}

/*************************************** PRINTER ********************************************************/

/* The Super80 had an optional I/O card that plugged into the S-100 slot. The card had facility for running
    an 8-bit Centronics printer, and a serial device at 300, 600, or 1200 baud. The I/O address range
    was selectable via 4 dipswitches. The serial parameters (baud rate, parity, stop bits, etc) was
    chosen with more dipswitches. Regretably, no parameters could be set by software. Currently, the
    Centronics printer is emulated; the serial side of things may be done later, as will the dipswitches.

    The most commonly used I/O range is DC-DE (DC = centronics, DD = serial data, DE = serial control
    All the home-brew roms use this, except for super80e which uses BC-BE. */

/**************************** I/O PORTS *****************************************************************/

READ8_MEMBER( super80_state::port3e_r )
{
	return 0xF8 | (m_fdc->intrq_r() << 0) | (m_fdc->drq_r() << 1) | 4;
}

// UFDC board can support 4 drives; we support 2
WRITE8_MEMBER( super80_state::port3f_w )
{
	// m_fdc->58(BIT(data, 0));   5/8 pin not emulated in wd_fdc
	m_fdc->enmf_w(BIT(data,1));

	floppy_image_device *floppy = nullptr;
	if (BIT(data, 2)) floppy = m_floppy0->get_device();
	if (BIT(data, 3)) floppy = m_floppy1->get_device();
	//if (BIT(data, 4)) floppy = m_floppy2->get_device();
	//if (BIT(data, 5)) floppy = m_floppy3->get_device();

	m_fdc->set_floppy(floppy);

	if (floppy)
	{
		floppy->mon_w(0);
		floppy->ss_w(!BIT(data, 6));
	}

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

READ8_MEMBER( super80_state::super80_f2_r )
{
	uint8_t data = m_io_dsw->read() & 0xf0;  // dip switches on pcb
	data |= m_cass_data[2];         // bit 0 = output of U1, bit 1 = MDS cass state, bit 2 = current wave_state
	data |= 0x08;               // bit 3 - not used
	return data;
}

WRITE8_MEMBER( super80_state::super80_dc_w )
{
	/* hardware strobe driven from port select, bit 7..0 = data */
	m_cent_data_out->write(space, 0, data);
	m_centronics->write_strobe(0);
	m_centronics->write_strobe(1);
}


WRITE8_MEMBER( super80_state::super80_f0_w )
{
	uint8_t bits = data ^ m_last_data;
	m_portf0 = data;
	m_speaker->level_w(BIT(data, 3));               /* bit 3 - speaker */
	if (BIT(bits, 1)) super80_cassette_motor(BIT(data, 1));  /* bit 1 - cassette motor */
	m_cassette->output( BIT(data, 0) ? -1.0 : +1.0);    /* bit 0 - cass out */

	m_last_data = data;
}

WRITE8_MEMBER( super80_state::super80r_f0_w )
{
	uint8_t bits = data ^ m_last_data;
	m_portf0 = data | 0x14;
	m_speaker->level_w(BIT(data, 3));               /* bit 3 - speaker */
	if (BIT(bits, 1)) super80_cassette_motor(BIT(data, 1));  /* bit 1 - cassette motor */
	m_cassette->output( BIT(data, 0) ? -1.0 : +1.0);    /* bit 0 - cass out */

	m_last_data = data;
}

/**************************** BASIC MACHINE CONSTRUCTION ***********************************************************/

MACHINE_RESET_MEMBER( super80_state, super80 )
{
	m_portf0 = 0; // must be 0 like real machine, or banking breaks on 32-col systems
	m_keylatch = 0xff;
	m_key_pressed = 0;
	m_palette_index = 0;
	machine().scheduler().timer_set(attotime::from_usec(10), timer_expired_delegate(FUNC(super80_state::super80_reset),this));
	membank("boot")->set_entry(1);
}

MACHINE_RESET_MEMBER( super80_state, super80r )
{
	m_portf0 = 0x14;
	m_keylatch = 0xff;
	m_key_pressed = 0;
	m_palette_index = 0;
	machine().scheduler().timer_set(attotime::from_usec(10), timer_expired_delegate(FUNC(super80_state::super80_reset),this));
	membank("boot")->set_entry(1);
}

void super80_state::init_super80()
{
	uint8_t *RAM = memregion("maincpu")->base();
	membank("boot")->configure_entries(0, 2, &RAM[0x0000], 0xc000);
}


/*-------------------------------------------------
    QUICKLOAD_LOAD_MEMBER( super80_state, super80 )
-------------------------------------------------*/

QUICKLOAD_LOAD_MEMBER( super80_state, super80 )
{
	uint16_t exec_addr, start_addr, end_addr;

	/* load the binary into memory */
	if (z80bin_load_file(&image, m_maincpu->space(AS_PROGRAM), file_type, &exec_addr, &start_addr, &end_addr) != image_init_result::PASS)
		return image_init_result::FAIL;

	/* is this file executable? */
	if (exec_addr != 0xffff)
		/* check to see if autorun is on */
		if (BIT(m_io_config->read(), 0))
			m_maincpu->set_pc(exec_addr);

	return image_init_result::PASS;
}