summaryrefslogblamecommitdiffstatshomepage
path: root/src/mame/machine/primo.cpp
blob: 3166b3eb9546fe507d87dbd198d8db9983be8005 (plain) (tree)
1
2
                       
                                       
















                                                                                
                   








                                                                                
                                          
 
                           
                                                                            







                                                                                
                                       
 

                                                            
         
                                              
                                                          
                                                                                           
                              
                                                   
                                                          
                                                                        
                              
                                     
                                                                          
                                                                                 
                              
                                                   
                                                          
                                                                        

                              
                                                      









                                                                                
                            




                                                                              
                                                 





                                    
                                                          











                                                                                                              
                            




























                                                 







                                                         
                                         












                                                         
                                                 


                              
                                                

                              
                                                





                                        


                              
                                         

                        
                                          



                           
                                         

                      
                                         










                                                
                                      








                                                                                
                                                               
 
                         

 
                                




                                       
                                




                                       
                                










                                                                                
                                             
 
                                   

                                 
                                                                     

 

                                 


                                                                                                          

 
                                 
 
                                    

 
                                        
 
                                    










                                                                                
                                                                                  
 
                           













                                                                                     




                                                    
                                                   

                               
                                                      


                    

                                                                                           

 
                                              
 
                                                          
 
                                                                           
         
                                               

         
                                                          
         
                                               

         
                                                          
 
                                       








                                                                                
                                                                                  
 

                            



                                                               
                                                
                                                                                           
 
                                                     



                                                                                                      
                                                
 
                                                            
 
                                                                              
         
                                               

         
                                                           
 
                                       
 
// license:BSD-3-Clause
// copyright-holders:Krzysztof Strzecha
/*******************************************************************************

    primo.c

    Functions to emulate general aspects of Microkey Primo computers
    (RAM, ROM, interrupts, I/O ports)

    Krzysztof Strzecha

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

/* Core includes */
#include "emu.h"
#include "includes/primo.h"

/* Components */
#include "cpu/z80/z80.h"
#include "screen.h"



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

    Interrupt callback

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

WRITE_LINE_MEMBER(primo_state::vblank_irq)
{
	if (state && m_nmi)
		m_maincpu->pulse_input_line(INPUT_LINE_NMI, attotime::zero);
}

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

    Memory banking

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

void primo_state::primo_update_memory()
{
	address_space& space = m_maincpu->space(AS_PROGRAM);
	switch (m_port_FD & 0x03)
	{
		case 0x00:  /* Original ROM */
			space.unmap_write(0x0000, 0x3fff);
			membank("bank1")->set_base(memregion("maincpu")->base() + 0x10000);
			break;
		case 0x01:  /* EPROM extension 1 */
			space.unmap_write(0x0000, 0x3fff);
			membank("bank1")->set_base(m_cart2_rom->base());
			break;
		case 0x02:  /* RAM */
			space.install_write_bank(0x0000, 0x3fff, "bank1");
			membank("bank1")->set_base(memregion("maincpu")->base());
			break;
		case 0x03:  /* EPROM extension 2 */
			space.unmap_write(0x0000, 0x3fff);
			membank("bank1")->set_base(m_cart1_rom->base());
			break;
	}
	logerror ("Memory update: %02x\n", m_port_FD);
}

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

    IO read/write handlers

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

READ8_MEMBER(primo_state::primo_be_1_r)
{
	uint8_t data = 0x00;
	static const char *const portnames[] = { "IN0", "IN1", "IN2", "IN3" };

	// bit 7, 6 - not used

	// bit 5 - VBLANK
	data |= m_screen->vblank() ? 0x20 : 0x00;

	// bit 4 - I4 (external bus)

	// bit 3 - I3 (external bus)

	// bit 2 - cassette
	data |= (m_cassette->input() < 0.1) ? 0x04 : 0x00;

	// bit 1 - reset button
	data |= (ioport("RESET")->read()) ? 0x02 : 0x00;

	// bit 0 - keyboard
	data |= (ioport(portnames[(offset & 0x0030) >> 4])->read() >> (offset&0x000f)) & 0x0001 ? 0x01 : 0x00;

	return data;
}

READ8_MEMBER(primo_state::primo_be_2_r)
{
	uint8_t data = 0xff;

	// bit 7, 6 - not used

	// bit 5 - SCLK
	if (!m_iec->clk_r())
		data &= ~0x20;

	// bit 4 - SDATA
	if (!m_iec->data_r())
		data &= ~0x10;

	// bit 3 - SRQ
	if (!m_iec->srq_r())
		data &= ~0x08;

	// bit 2 - joystic 2 (not implemeted yet)

	// bit 1 - ATN
	if (!m_iec->atn_r())
		data &= ~0x02;

	// bit 0 - joystic 1 (not implemeted yet)

	logerror ("IOR BE-2 data:%02x\n", data);
	return data;
}

WRITE8_MEMBER(primo_state::primo_ki_1_w)
{
	// bit 7 - NMI generator enable/disable
	m_nmi = (data & 0x80) ? 1 : 0;

	// bit 6 - joystick register shift (not emulated)

	// bit 5 - V.24 (2) / tape control (not emulated)

	// bit 4 - speaker
	m_speaker->level_w(BIT(data, 4));

	// bit 3 - display buffer
	if (data & 0x08)
		m_video_memory_base |= 0x2000;
	else
		m_video_memory_base &= 0xdfff;

	// bit 2 - V.24 (1) / tape control (not emulated)

	// bit 1, 0 - cassette output
	switch (data & 0x03)
	{
		case 0:
			m_cassette->output(-1.0);
			break;
		case 1:
		case 2:
			m_cassette->output(0.0);
			break;
		case 3:
			m_cassette->output(1.0);
			break;
	}
}

WRITE8_MEMBER(primo_state::primo_ki_2_w)
{
	// bit 7, 6 - not used

	// bit 5 - SCLK
	m_iec->host_clk_w(!BIT(data, 5));

	// bit 4 - SDATA
	m_iec->host_data_w(!BIT(data, 4));

	// bit 3 - not used

	// bit 2 - SRQ
	m_iec->host_srq_w(!BIT(data, 2));

	// bit 1 - ATN
	m_iec->host_atn_w(!BIT(data, 1));

	// bit 0 - not used

//  logerror ("IOW KI-2 data:%02x\n", data);
}

WRITE8_MEMBER(primo_state::primo_FD_w)
{
	if (!ioport("MEMORY_EXPANSION")->read())
	{
		m_port_FD = data;
		primo_update_memory();
	}
}

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

    Driver initialization

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

void primo_state::primo_common_driver_init (primo_state *state)
{
	m_port_FD = 0x00;
}

void primo_state::init_primo32()
{
	primo_common_driver_init(this);
	m_video_memory_base = 0x6800;
}

void primo_state::init_primo48()
{
	primo_common_driver_init(this);
	m_video_memory_base = 0xa800;
}

void primo_state::init_primo64()
{
	primo_common_driver_init(this);
	m_video_memory_base = 0xe800;
}

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

    Machine initialization

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

void primo_state::primo_common_machine_init()
{
	if (m_mem_exp_port->read())
		m_port_FD = 0x00;
	primo_update_memory();
	m_maincpu->set_clock_scale(m_clock_port->read() ? 1.5 : 1.0);
}

void primo_state::machine_start()
{
	std::string region_tag;
	m_cart1_rom = memregion(region_tag.assign(m_cart1->tag()).append(GENERIC_ROM_REGION_TAG).c_str());
	m_cart2_rom = memregion(region_tag.assign(m_cart2->tag()).append(GENERIC_ROM_REGION_TAG).c_str());
}

void primo_state::machine_reset()
{
	primo_common_machine_init();
}

MACHINE_RESET_MEMBER(primo_state,primob)
{
	primo_common_machine_init();

//removed   cbm_drive_0_config(SERIAL, 8);
//removed   cbm_drive_1_config(SERIAL, 9);
}

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

    Snapshot files (.pss)

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

void primo_state::primo_setup_pss (uint8_t* snapshot_data, uint32_t snapshot_size)
{
	/* Z80 registers */
	m_maincpu->set_state_int(Z80_BC, snapshot_data[4] + snapshot_data[5]*256);
	m_maincpu->set_state_int(Z80_DE, snapshot_data[6] + snapshot_data[7]*256);
	m_maincpu->set_state_int(Z80_HL, snapshot_data[8] + snapshot_data[9]*256);
	m_maincpu->set_state_int(Z80_AF, snapshot_data[10] + snapshot_data[11]*256);
	m_maincpu->set_state_int(Z80_BC2, snapshot_data[12] + snapshot_data[13]*256);
	m_maincpu->set_state_int(Z80_DE2, snapshot_data[14] + snapshot_data[15]*256);
	m_maincpu->set_state_int(Z80_HL2, snapshot_data[16] + snapshot_data[17]*256);
	m_maincpu->set_state_int(Z80_AF2, snapshot_data[18] + snapshot_data[19]*256);
	m_maincpu->set_state_int(Z80_PC, snapshot_data[20] + snapshot_data[21]*256);
	m_maincpu->set_state_int(Z80_SP, snapshot_data[22] + snapshot_data[23]*256);
	m_maincpu->set_state_int(Z80_I, snapshot_data[24]);
	m_maincpu->set_state_int(Z80_R, snapshot_data[25]);
	m_maincpu->set_state_int(Z80_IX, snapshot_data[26] + snapshot_data[27]*256);
	m_maincpu->set_state_int(Z80_IY, snapshot_data[28] + snapshot_data[29]*256);


	/* IO ports */

	// KI-1 bit 7 - NMI generator enable/disable
	m_nmi = (snapshot_data[30] & 0x80) ? 1 : 0;

	// KI-1 bit 4 - speaker
	m_speaker->level_w(BIT(snapshot_data[30], 4));


	/* memory */
	for (int i = 0; i < 0xc000; i++)
		m_maincpu->space(AS_PROGRAM).write_byte(i + 0x4000, snapshot_data[i + 38]);
}

SNAPSHOT_LOAD_MEMBER(primo_state::snapshot_cb)
{
	std::vector<uint8_t> snapshot_data(snapshot_size);

	if (image.fread(&snapshot_data[0], snapshot_size) != snapshot_size)
	{
		return image_init_result::FAIL;
	}

	if (strncmp((char *)&snapshot_data[0], "PS01", 4))
	{
		return image_init_result::FAIL;
	}

	primo_setup_pss(&snapshot_data[0], snapshot_size);

	return image_init_result::PASS;
}

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

    Quicload files (.pp)

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


void primo_state::primo_setup_pp(uint8_t* quickload_data, uint32_t quickload_size)
{
	uint16_t load_addr;
	uint16_t start_addr;

	load_addr = quickload_data[0] + quickload_data[1]*256;
	start_addr = quickload_data[2] + quickload_data[3]*256;

	for (int i = 4; i < quickload_size; i++)
		m_maincpu->space(AS_PROGRAM).write_byte(start_addr+i-4, quickload_data[i]);

	m_maincpu->set_state_int(Z80_PC, start_addr);

	logerror ("Quickload .pp l: %04x r: %04x s: %04x\n", load_addr, start_addr, quickload_size-4);
}

QUICKLOAD_LOAD_MEMBER(primo_state::quickload_cb)
{
	std::vector<uint8_t> quickload_data(quickload_size);

	if (image.fread(&quickload_data[0], quickload_size) != quickload_size)
	{
		return image_init_result::FAIL;
	}

	primo_setup_pp(&quickload_data[0], quickload_size);

	return image_init_result::PASS;
}