summaryrefslogblamecommitdiffstatshomepage
path: root/src/mame/machine/mbc55x.cpp
blob: de0155bbe3f4cb66667910bde2166b645088f4d3 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
                       
                                       








                                                                              
                

                     
                            
                           









                                                                             
                                     


                                     
                                     




                                                                



                                                                




































                                                 
                                              















                                                        

 












                                             

                                        
                                             



                                         
                                             

 

                                        
                                               



                                         
                                               



                                             
                                    
                                    

















                                                                                    
                                             



                                          
                                             

 





                      
                                   
 

                                       

                                                       

                                        
                                                                                   

 
                                  
 



                         
 
                    








                                                               






                                                                 






                                                                 




                                                                



                                              
                                                                 


                                             
                                                       


                                                                     
                                                                                
                         
                                                                                              




                                                                                
                                                                  


                         
                                               


         
                                                     
 
                        

 

                                             
                           



                       








                                                                                                             










                                              

                                                                      


         
                                 
 

                                                                     


                                                              

                                                             
                                  














                                                                         
                                                          
                                                                                                   



                                                                                      
                                                                                    




                                                                                      
                                                                         
                                                                                                                
                                                                           
                                                                                                                   

 
                                


 
                                  
 

                         

 
                                  
 
                      
                      


                                  
                                                       
         
                                                  
                                                                                                                                                              

                                                 
                                                                           

         
                                   

                                 
                                                                                                                                      


 
                                                                                 
 
                              
         
                         
                                                       
                                       


            

                                                                                                    








                                                           

                                                                              
                                   
 
                                                       
 
                                                        











                                                                  

                                                                               











                                                             
 





                                                                                                      

                                 
         
                                                
         
 
// license:BSD-3-Clause
// copyright-holders:Phill Harvey-Smith
/*
    machine/mbc55x.c

    Machine driver for the Sanyo MBC-550 and MBC-555.

    Phill Harvey-Smith
    2011-01-29.
*****************************************************************************/

#include "emu.h"
#include <functional>

#include "includes/mbc55x.h"
#include "debug/debugcpu.h"


/*-------------------------------------------------------------------------*/
/* Defines, constants, and global variables                                */
/*-------------------------------------------------------------------------*/

/* Debugging */

#define DEBUG_SET(flags)    ((state->m_debug_machine & (flags))==(flags))

#define DEBUG_NONE          0x0000000
#define DMA_BREAK           0x0000001
#define DECODE_BIOS         0x0000002
#define DECODE_BIOS_RAW     0x0000004
#define DECODE_DOS21        0x0000008

#define LOG_KEYBOARD        1

static void decode_dos21(device_t *device,offs_t pc);
//static void mbc55x_recalculate_ints(running_machine &machine);
static int instruction_hook(device_t &device, offs_t curpc);
//static void fdc_reset(running_machine &machine);
//static void set_disk_int(running_machine &machine, int state);

/* 8255 Configuration */

READ8_MEMBER( mbc55x_state::ppi8255_r )
{
	return m_ppi->read(space, offset>>1);
}

WRITE8_MEMBER( mbc55x_state::ppi8255_w )
{
	m_ppi->write(space, offset>>1, data);
}

READ8_MEMBER( mbc55x_state::mbc55x_ppi_porta_r )
{
	return 0xff;
}

READ8_MEMBER( mbc55x_state::mbc55x_ppi_portb_r )
{
	return 0xff;
}

READ8_MEMBER( mbc55x_state::mbc55x_ppi_portc_r )
{
	return 0xff;
}

WRITE8_MEMBER( mbc55x_state::mbc55x_ppi_porta_w )
{
}

WRITE8_MEMBER( mbc55x_state::mbc55x_ppi_portb_w )
{
}

WRITE8_MEMBER( mbc55x_state::mbc55x_ppi_portc_w )
{
	floppy_image_device *floppy = nullptr;

	switch (data & 0x03)
	{
	case 0: floppy = m_floppy0->get_device(); break;
	case 1: floppy = m_floppy1->get_device(); break;
	case 2: floppy = m_floppy2->get_device(); break;
	case 3: floppy = m_floppy3->get_device(); break;
	}

	m_fdc->set_floppy(floppy);

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

/* Serial port USART, unimplemented as yet */

READ8_MEMBER( mbc55x_state::mbc55x_usart_r )
{
	return 0;
}

WRITE8_MEMBER( mbc55x_state::mbc55x_usart_w )
{
}

/* PIC 8259 Configuration */

READ8_MEMBER(mbc55x_state::mbcpic8259_r)
{
	return m_pic->read(space, offset>>1);
}

WRITE8_MEMBER(mbc55x_state::mbcpic8259_w)
{
	m_pic->write(space, offset>>1, data);
}

READ8_MEMBER(mbc55x_state::mbcpit8253_r)
{
	return m_pit->read(space, offset >> 1);
}

WRITE8_MEMBER(mbc55x_state::mbcpit8253_w)
{
	m_pit->write(space, offset >> 1, data);
}

WRITE_LINE_MEMBER( mbc55x_state::pit8253_t2 )
{
	m_kb_uart->write_txc(state);
	m_kb_uart->write_rxc(state);
}

/* Video ram page register */

READ8_MEMBER( mbc55x_state::vram_page_r )
{
	return m_vram_page;
}

WRITE8_MEMBER( mbc55x_state::vram_page_w )
{
	logerror("%s : set vram page to %02X\n", machine().describe_context(),data);

	m_vram_page=data;
}

READ8_MEMBER(mbc55x_state::mbc55x_disk_r)
{
	return m_fdc->read(space, offset>>1);
}

WRITE8_MEMBER(mbc55x_state::mbc55x_disk_w)
{
	m_fdc->write(space, offset>>1, data);
}


/*
    Keyboard emulation

*/

void mbc55x_state::keyboard_reset()
{
	logerror("keyboard_reset()\n");

	memset(m_keyboard.keyrows,0xFF,MBC55X_KEYROWS);
	m_keyboard.key_special=0;

	// Setup timer to scan keyboard.
	m_keyboard.keyscan_timer->adjust(attotime::zero, 0, attotime::from_hz(50));
}

void mbc55x_state::scan_keyboard()
{
	uint8_t   keyrow;
	uint8_t   row;
	uint8_t   bitno;
	uint8_t   mask;

	char    key;
	static const char *const keynames[] =
	{
		"KEY0", "KEY1", "KEY2", "KEY3", "KEY4",
		"KEY5", "KEY6", "KEY7", "KEY8", "KEY9",
		"KEY10"
	};

	static const char keyvalues_normal[MBC55X_KEYROWS][8] =
	{
		{ '1',  '2', '3', '4' , '5',  '6',  '7',  '8'  },
		{ '9',  '0', '-', '=',  '\\', 'q',  'w',  'e' },
		{ 'r',  't', 'y', 'u',  'i',  'o',  'p',  '[' },
		{ ']',  'a', 's', 'd',  'f',  'g',  'h',  'j' },
		{ 'k',  'l', ';', '\'', '`',  0x0D,  'z',  'x' },
		{ 'c',  'v', 'b', 'n',  'm',  ',',  '.',  '/', },
		{ ' ',  ' ', ' ', ' ',  ' ',  ' ',  ' ',  ' ', }

	};

	static const char keyvalues_shift[MBC55X_KEYROWS][8] =
	{
		{ '!',  '@', '#', '$' , '%',  '^',  '&',  '*'  },
		{ '(',  ')', '_', '+',  '|',  'Q',  'W',  'E'  },
		{ 'R',  'T', 'Y', 'U',  'I',  'O',  'P',  '{' },
		{ '}',  'A', 'S', 'D',  'F',  'G',  'H',  'J' },
		{ 'K',  'L', ':', '"',  '~',  0x0d, 'Z',  'X' },
		{ 'C',  'V', 'B', 'N',  'M',  ',',  '?',  '/' },
		{ ' ',  ' ', ' ', ' ',  ' ',  ' ',  ' ',  ' ' }
	};

	// First read shift, control and graph

	m_keyboard.key_special = ioport(KEY_SPECIAL_TAG)->read();

	for(row=0; row<MBC55X_KEYROWS; row++)
	{
		keyrow = ioport(keynames[row])->read();

		for(mask=0x80, bitno=7;mask>0;mask=mask>>1, bitno-=1)
		{
			if(!(keyrow & mask) && (m_keyboard.keyrows[row] & mask))
			{
				if(m_keyboard.key_special & (KEY_BIT_LSHIFT | KEY_BIT_RSHIFT))
					key=keyvalues_shift[row][bitno];
				else
					key=keyvalues_normal[row][bitno];

				if (LOG_KEYBOARD) logerror("keypress %c\n",key);
				m_kb_uart->receive_character(key);
			}
		}

		m_keyboard.keyrows[row]=keyrow;
	}
}

TIMER_CALLBACK_MEMBER(mbc55x_state::keyscan_callback)
{
	scan_keyboard();
}

READ8_MEMBER(mbc55x_state::mbc55x_kb_usart_r)
{
	uint8_t result = 0;
	offset>>=1;

	switch (offset)
	{
		case 0: //logerror("%s read kb_uart\n",machine().describe_context());
			result = m_kb_uart->data_r(space,0);
			break;

		case 1:
			result = m_kb_uart->status_r(space,0);
			if (m_keyboard.key_special & KEY_BIT_CTRL)  // Parity error used to flag control down
				result |= i8251_device::I8251_STATUS_PARITY_ERROR;
			break;
	}

	return result;
}

WRITE8_MEMBER(mbc55x_state::mbc55x_kb_usart_w)
{
	offset>>=1;

	switch (offset)
	{
		case 0  : m_kb_uart->data_w(space, 0, data); break;
		case 1  : m_kb_uart->control_w(space, 0, data); break;
	}
}

void mbc55x_state::set_ram_size()
{
	address_space   &space      = m_maincpu->space( AS_PROGRAM );
	int             ramsize     = m_ram->size();
	int             nobanks     = ramsize / RAM_BANK_SIZE;
	char            bank[10];
	int             bankno;
	uint8_t           *ram        = &m_ram->pointer()[0];
	uint8_t           *map_base;
	int             bank_base;


	logerror("Ramsize is %d bytes\n",ramsize);
	logerror("RAM_BANK_SIZE=%d, nobanks=%d\n",RAM_BANK_SIZE,nobanks);

	// Main memory mapping

	for(bankno=0; bankno<RAM_BANK_COUNT; bankno++)
	{
		sprintf(bank,"bank%x",bankno);
		bank_base=bankno*RAM_BANK_SIZE;
		map_base=&ram[bank_base];

		if(bankno<nobanks)
		{
			membank(bank)->set_base(map_base);
			space.install_readwrite_bank(bank_base, bank_base+(RAM_BANK_SIZE-1), bank);
			logerror("Mapping bank %d at %05X to RAM\n",bankno,bank_base);
		}
		else
		{
			space.nop_readwrite(bank_base, bank_base+(RAM_BANK_SIZE-1));
			logerror("Mapping bank %d at %05X to NOP\n",bankno,bank_base);
		}
	}

	// Graphics red and blue plane memory mapping, green is in main memory
	membank(RED_PLANE_TAG)->set_base(&m_video_mem[RED_PLANE_OFFSET]);
	space.install_readwrite_bank(RED_PLANE_MEMBASE, RED_PLANE_MEMBASE+(COLOUR_PLANE_SIZE-1), RED_PLANE_TAG);
	membank(BLUE_PLANE_TAG)->set_base(&m_video_mem[BLUE_PLANE_OFFSET]);
	space.install_readwrite_bank(BLUE_PLANE_MEMBASE, BLUE_PLANE_MEMBASE+(COLOUR_PLANE_SIZE-1), BLUE_PLANE_TAG);
}

void mbc55x_state::init_mbc55x()
{
}

void mbc55x_state::machine_reset()
{
	set_ram_size();
	keyboard_reset();
}

void mbc55x_state::machine_start()
{
	/* init cpu */
//  mbc55x_cpu_init();


	/* setup debug commands */
	if (machine().debug_flags & DEBUG_FLAG_ENABLED)
	{
		using namespace std::placeholders;
		machine().debugger().console().register_command("mbc55x_debug", CMDFLAG_NONE, 0, 0, 1, std::bind(&mbc55x_state::debug_command, this, _1, _2));

		/* set up the instruction hook */
		m_maincpu->debug()->set_instruction_hook(instruction_hook);
	}

	m_debug_machine=DEBUG_NONE;

	// Allocate keyscan timer
	m_keyboard.keyscan_timer=machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(mbc55x_state::keyscan_callback),this));
}


void mbc55x_state::debug_command(int ref, const std::vector<std::string> &params)
{
	if (params.size() > 0)
	{
		int temp;
		sscanf(params[0].c_str(), "%d", &temp);
		m_debug_machine = temp;
	}
	else
	{
		machine().debugger().console().printf("Error usage : mbc55x_debug <debuglevel>\n");
		machine().debugger().console().printf("Current debuglevel=%02X\n", m_debug_machine);
	}
}

/*-----------------------------------------------
    instruction_hook - per-instruction hook
-----------------------------------------------*/

static int instruction_hook(device_t &device, offs_t curpc)
{
	mbc55x_state    *state = device.machine().driver_data<mbc55x_state>();
	address_space   &space = device.memory().space(AS_PROGRAM);
	uint8_t          *addr_ptr;

	addr_ptr = (uint8_t*)space.get_read_ptr(curpc);

	if ((addr_ptr !=nullptr) && (addr_ptr[0]==0xCD))
	{
//      logerror("int %02X called\n",addr_ptr[1]);

		if(DEBUG_SET(DECODE_DOS21) && (addr_ptr[1]==0x21))
			decode_dos21(&device,curpc);
	}

	return 0;
}

static void decode_dos21(device_t *device,offs_t pc)
{
	mbc55x_state    *state = device->machine().driver_data<mbc55x_state>();

	uint16_t  ax = state->m_maincpu->state_int(I8086_AX);
	uint16_t  bx = state->m_maincpu->state_int(I8086_BX);
	uint16_t  cx = state->m_maincpu->state_int(I8086_CX);
	uint16_t  dx = state->m_maincpu->state_int(I8086_DX);
	uint16_t  cs = state->m_maincpu->state_int(I8086_CS);
	uint16_t  ds = state->m_maincpu->state_int(I8086_DS);
	uint16_t  es = state->m_maincpu->state_int(I8086_ES);
	uint16_t  ss = state->m_maincpu->state_int(I8086_SS);

	uint16_t  si = state->m_maincpu->state_int(I8086_SI);
	uint16_t  di = state->m_maincpu->state_int(I8086_DI);
	uint16_t  bp = state->m_maincpu->state_int(I8086_BP);

	device->logerror("=======================================================================\n");
	device->logerror("DOS Int 0x21 call at %05X\n",pc);
	device->logerror("AX=%04X, BX=%04X, CX=%04X, DX=%04X\n",ax,bx,cx,dx);
	device->logerror("CS=%04X, DS=%04X, ES=%04X, SS=%04X\n",cs,ds,es,ss);
	device->logerror("SI=%04X, DI=%04X, BP=%04X\n",si,di,bp);
	device->logerror("=======================================================================\n");

	if((ax & 0xff00)==0x0900)
	{
		device->machine().debug_break();
	}
}