summaryrefslogblamecommitdiffstatshomepage
path: root/src/mame/drivers/amust.cpp
blob: 0301b5ba7f640fe0b8fa1eec938e3b68050d5a80 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
                       


                                                                            
                                                 
 



                                                  
                               
                                                                               
                                                                          
                                                                       
                                                                   



                                                                           


                                                                       














                                                                           
 
 
                  
                  









                     
 



                                                                                     
                                                                                    









                                                                                     
                 
                 



                                


               
                                          
                                                                                      
 




                                                                             

                          
                            

                            
                           
                       


                         




                                        




                              
                                                                                     


                                                   

                                                 
                                         




                                           
                          
                                     





                                        


                                        
                                        
                                        
                              
                                     
                                           
 
                                           

                                       
        




                       
                                                                                                       
                                                  
                                              

                                             
                                            




                                                    







                                                                                          
                                                                                


         

                                        

                                               
                                          



                                                       

   






















                                                                                                     
 



                                                         


                                 










                                                                    

               


                                           
                                                                                 





















                                      
                                    




                                      




                                     
                                




                                      









                                          

                                     
                                                      
                                    






                                     






                                             

                                      
                        





                                                                    

 

                                      
                                                                  


                                           













                                                             
                                   


                                                                    
                                                 
 
                                                                      


                                  




                                                 
                                        
                           
                                                               














                                                                  
                                          
 

                                                               
                                                            

                                     



                     


                                                 
                              
 
                                                





                                                              
                                        
                                    



                                                                    
                                                       

                            
                                                                    




                                                                             
                                              
                                                                     
 
                            
                                               
                                            

                                                   
                     
                                                                       



                                                               
                                            
                                                                                                            
                                     
                                                                                                            
                                     
 
                                                    

                                                                              

                                          


                                                                                
 



                                                                               
 
                                          


                                                                                  
 
                                          

                                          




                                                                     

                                          




                                                                     









                                                                                                              
                                          
                                                                                                           
 




                                                          

                                                                                                                                 
// license:BSD-3-Clause
// copyright-holders:Robbbert
/***************************************************************************

Amust Compak - also known as Amust Executive 816.

2014-03-21 Skeleton driver. [Robbbert]

An unusual-looking CP/M computer.
There are no manuals or schematics known to exist.
The entire driver is guesswork.
The board has LH0080 (Z80A), 2x 8251, 2x 8255, 8253, uPD765A and a HD46505SP-2.
The videoram is a 6116 RAM. There is a piezo beeper. There are 3 crystals,
X1 = 4.9152 (serial chips?), X2 = 16 (CPU), X3 = 14.31818 MHz (Video?).
There are numerous jumpers, all of which perform unknown functions.

The keyboard is a plug-in unit, same idea as Kaypro and Zorba. It has these
chips: INS8035N-6, F74145, 74LS373N, SN75451BP, 2716 rom with label KBD-3.
Crystal: 3.579545 MHz

The main rom is identical between the 2 halves, except that the initial
crtc parameters are slightly different. I've chosen to ignore the first
half. (perhaps 50/60 Hz selectable by jumper?)

Preliminary I/O ports
---------------------
00-01 uart 1
02-03 uart 2
04-07 ppi 1
08-0b ppi 2
0d-0f crtc
10-11 fdc
14-17 pit

PIT.
Having the PIT on ports 14-17 seems to make sense. It sets counters 1 and 2
to mode 3, binary, initial count = 0x80. Counter 0 not used?


Floppy Parameters:
------------------
Double Density
Two Side
80 track
1024 byte sectors
5 sectors/track
800k capacity
128 directory entries
2k block size
Skew 1,3,5,2,4


Stuff that doesn't make sense:
------------------------------
1. To access the screen, it waits for IRQ presumably from sync pulse. It sets INT
mode 0 which means a page-zero jump, but doesn't write anything to the zero-page ram.
That's why I added a RETI at 0038 and set the vector to there. A bit later it writes
a jump at 0000. Then it sets the interrupting device to the fdc (not sure how yet),
then proceeds to overwrite all of page-zero with the disk contents. This of course
kills the jump it just wrote, and my RETI. So it runs into the weeds at high speed.
What should happen is after loading the boot sector succesfully it will jump to 0000,
otherwise it will write BOOT NG to the screen and you're in the monitor. The bios
contains no RETI instructions.
2. At F824 it copies itself to the same address which is presumably shadow ram. But
it never switches to it. The ram is physically in the machine.


Monitor Commands:
-----------------
B = Boot from floppy
(YES! Most useless monitor ever)


ToDo:
- Everything
- Need software
- Keyboard controller needs to be emulated
- If booting straight to CP/M, the load message should be in the middle of the screen.


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

#include "emu.h"
#include "cpu/z80/z80.h"
#include "machine/i8251.h"
#include "machine/i8255.h"
#include "machine/pit8253.h"
#include "machine/clock.h"
#include "bus/rs232/rs232.h"
#include "machine/upd765.h"
#include "sound/beep.h"
#include "video/mc6845.h"
#include "screen.h"
#include "speaker.h"


class amust_state : public driver_device
{
public:
	enum
	{
		TIMER_BEEP_OFF
	};

	amust_state(const machine_config &mconfig, device_type type, const char *tag)
		: driver_device(mconfig, type, tag)
		, m_palette(*this, "palette")
		, m_maincpu(*this, "maincpu")
		, m_p_videoram(*this, "videoram")
		, m_p_chargen(*this, "chargen")
		, m_beep(*this, "beeper")
		, m_fdc (*this, "fdc")
		, m_floppy0(*this, "fdc:0")
		, m_floppy1(*this, "fdc:1")
	{ }

	void init_amust();
	DECLARE_MACHINE_RESET(amust);
	DECLARE_READ8_MEMBER(port04_r);
	DECLARE_WRITE8_MEMBER(port04_w);
	DECLARE_READ8_MEMBER(port05_r);
	DECLARE_READ8_MEMBER(port06_r);
	DECLARE_WRITE8_MEMBER(port06_w);
	DECLARE_READ8_MEMBER(port08_r);
	DECLARE_WRITE8_MEMBER(port08_w);
	DECLARE_READ8_MEMBER(port09_r);
	DECLARE_READ8_MEMBER(port0a_r);
	DECLARE_WRITE8_MEMBER(port0a_w);
	DECLARE_WRITE8_MEMBER(port0d_w);
	void kbd_put(u8 data);
	INTERRUPT_GEN_MEMBER(irq_vs);
	MC6845_UPDATE_ROW(crtc_update_row);

	void amust(machine_config &config);
	void io_map(address_map &map);
	void mem_map(address_map &map);
private:
	u8 m_port04;
	u8 m_port06;
	u8 m_port08;
	u8 m_port0a;
	u8 m_term_data;
	virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
	required_device<palette_device> m_palette;
	required_device<cpu_device> m_maincpu;
	required_region_ptr<u8> m_p_videoram;
	required_region_ptr<u8> m_p_chargen;
	required_device<beep_device> m_beep;
	required_device<upd765a_device> m_fdc;
	required_device<floppy_connector> m_floppy0;
	required_device<floppy_connector> m_floppy1;
};

void amust_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
	switch (id)
	{
	case TIMER_BEEP_OFF:
		m_beep->set_state(0);
		break;
	default:
		assert_always(false, "Unknown id in amust_state::device_timer");
	}
}

//WRITE8_MEMBER( amust_state::port00_w )
//{
//  membank("bankr0")->set_entry(BIT(data, 6));
//  m_fdc->dden_w(BIT(data, 5));
//  floppy_image_device *floppy = nullptr;
//  if (BIT(data, 0)) floppy = m_floppy0->get_device();
//  m_fdc->set_floppy(floppy);
//  if (floppy)
//      floppy->ss_w(BIT(data, 4));
//}

void amust_state::mem_map(address_map &map)
{
	map.unmap_value_high();
	map(0x0000, 0xf7ff).ram();
	map(0xf800, 0xffff).bankr("bankr0").bankw("bankw0");
}

void amust_state::io_map(address_map &map)
{
	map.unmap_value_high();
	map.global_mask(0xff);
	map(0x00, 0x00).rw("uart1", FUNC(i8251_device::data_r), FUNC(i8251_device::data_w));
	map(0x01, 0x01).rw("uart1", FUNC(i8251_device::status_r), FUNC(i8251_device::control_w));
	map(0x02, 0x02).rw("uart2", FUNC(i8251_device::data_r), FUNC(i8251_device::data_w));
	map(0x03, 0x03).rw("uart2", FUNC(i8251_device::status_r), FUNC(i8251_device::control_w));
	map(0x04, 0x07).rw("ppi1", FUNC(i8255_device::read), FUNC(i8255_device::write));
	map(0x08, 0x0b).rw("ppi2", FUNC(i8255_device::read), FUNC(i8255_device::write));
	map(0x0d, 0x0d).nopr().w(this, FUNC(amust_state::port0d_w));
	map(0x0e, 0x0e).rw("crtc", FUNC(mc6845_device::status_r), FUNC(mc6845_device::address_w));
	map(0x0f, 0x0f).rw("crtc", FUNC(mc6845_device::register_r), FUNC(mc6845_device::register_w));
	map(0x10, 0x11).m(m_fdc, FUNC(upd765a_device::map));
	map(0x14, 0x17).rw("pit", FUNC(pit8253_device::read), FUNC(pit8253_device::write));
}

static void amust_floppies(device_slot_interface &device)
{
	device.option_add("525qd", FLOPPY_525_QD);
}

/* Input ports */
static INPUT_PORTS_START( amust )
	PORT_START("P9")
	// bits 6,7 not used?
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN ) // code @ FB83
	PORT_DIPNAME( 0x10, 0x10, "Boot to Monitor" ) // code @ F895
	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
	PORT_DIPSETTING(    0x10, DEF_STR( On ) )
	PORT_DIPNAME( 0x0f, 0x01, "Unknown" ) // code @ FC99
	PORT_DIPSETTING(    0x01, "1" )
	PORT_DIPSETTING(    0x02, "2" )
	PORT_DIPSETTING(    0x04, "3" )
	PORT_DIPSETTING(    0x08, "4" )
INPUT_PORTS_END

// bodgy
INTERRUPT_GEN_MEMBER( amust_state::irq_vs )
{
	m_maincpu->set_input_line_and_vector(INPUT_LINE_IRQ0, ASSERT_LINE, 0xff);
}

READ8_MEMBER( amust_state::port04_r )
{
	return m_port04;
}

WRITE8_MEMBER( amust_state::port04_w )
{
	m_port04 = data;
}

READ8_MEMBER( amust_state::port05_r )
{
	return 0;
}

READ8_MEMBER( amust_state::port06_r )
{
	return m_port06;
}

// BIT 5 low while writing to screen
WRITE8_MEMBER( amust_state::port06_w )
{
	m_port06 = data;
}

READ8_MEMBER( amust_state::port08_r )
{
	return m_port08;
}

// lower 8 bits of video address
WRITE8_MEMBER( amust_state::port08_w )
{
	m_port08 = data;
}

/*
d0 - something to do with type of disk
d1 -
d2 -
d3 -
d4 - H = go to monitor; L = boot from disk
d5 - status of disk-related; loops till NZ
d6 -
d7 -
*/
READ8_MEMBER( amust_state::port09_r )
{
	logerror("%s\n",machine().describe_context());
	return ioport("P9")->read();
}

READ8_MEMBER( amust_state::port0a_r )
{
	return m_port0a;
}

/* Bits 7,6,5,3 something to do
with selecting which device causes interrupt?
50, 58 = video sync
70 disk
D0 ?
Bit 4 low = beeper.
Lower 3 bits = upper part of video address */
WRITE8_MEMBER( amust_state::port0a_w )
{
	m_port0a = data;

	if (!BIT(data, 4))
	{
		m_beep->set_state(1);
		timer_set(attotime::from_msec(150), TIMER_BEEP_OFF);
	}
}

WRITE8_MEMBER( amust_state::port0d_w )
{
	uint16_t video_address = m_port08 | ((m_port0a & 7) << 8);
	m_p_videoram[video_address] = data;
}

/* F4 Character Displayer */
static const gfx_layout amust_charlayout =
{
	8, 8,                  /* 8 x 8 characters */
	256,                    /* 256 characters */
	1,                  /* 1 bits per pixel */
	{ 0 },                  /* no bitplanes */
	/* x offsets */
	{ 0, 1, 2, 3, 4, 5, 6, 7 },
	/* y offsets */
	{ 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8 },
	8*8                    /* every char takes 8 bytes */
};

static GFXDECODE_START( gfx_amust )
	GFXDECODE_ENTRY( "chargen", 0x0000, amust_charlayout, 0, 1 )
GFXDECODE_END

MC6845_UPDATE_ROW( amust_state::crtc_update_row )
{
	const rgb_t *palette = m_palette->palette()->entry_list_raw();
	u8 chr,gfx,inv;
	u16 mem,x;
	u32 *p = &bitmap.pix32(y);

	for (x = 0; x < x_count; x++)
	{
		inv = (x == cursor_x) ? 0xff : 0;
		mem = (ma + x) & 0x7ff;
		chr = m_p_videoram[mem];
		if (ra < 8)
			gfx = m_p_chargen[(chr<<3) | ra] ^ inv;
		else
			gfx = inv;

		/* Display a scanline of a character (8 pixels) */
		*p++ = palette[BIT(gfx, 7)];
		*p++ = palette[BIT(gfx, 6)];
		*p++ = palette[BIT(gfx, 5)];
		*p++ = palette[BIT(gfx, 4)];
		*p++ = palette[BIT(gfx, 3)];
		*p++ = palette[BIT(gfx, 2)];
		*p++ = palette[BIT(gfx, 1)];
		*p++ = palette[BIT(gfx, 0)];
	}
}

MACHINE_RESET_MEMBER( amust_state, amust )
{
	membank("bankr0")->set_entry(0); // point at rom
	membank("bankw0")->set_entry(0); // always write to ram
	address_space &space = m_maincpu->space(AS_PROGRAM);
	space.write_byte(0x38, 0xed);
	space.write_byte(0x39, 0x4d);
	m_port04 = 0;
	m_port06 = 0;
	m_port08 = 0;
	m_port0a = 0;
	m_maincpu->set_state_int(Z80_PC, 0xf800);
}

void amust_state::init_amust()
{
	u8 *main = memregion("maincpu")->base();

	membank("bankr0")->configure_entry(1, &main[0xf800]);
	membank("bankr0")->configure_entry(0, &main[0x10800]);
	membank("bankw0")->configure_entry(0, &main[0xf800]);
}

MACHINE_CONFIG_START(amust_state::amust)
	/* basic machine hardware */
	MCFG_DEVICE_ADD("maincpu",Z80, XTAL(16'000'000) / 4)
	MCFG_DEVICE_PROGRAM_MAP(mem_map)
	MCFG_DEVICE_IO_MAP(io_map)
	MCFG_DEVICE_VBLANK_INT_DRIVER("screen", amust_state, irq_vs)
	MCFG_MACHINE_RESET_OVERRIDE(amust_state, amust)

	/* video hardware */
	MCFG_SCREEN_ADD_MONOCHROME("screen", RASTER, rgb_t::green())
	MCFG_SCREEN_REFRESH_RATE(50)
	MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */
	MCFG_SCREEN_SIZE(640, 480)
	MCFG_SCREEN_VISIBLE_AREA(0, 640-1, 0, 480-1)
	MCFG_SCREEN_UPDATE_DEVICE("crtc", mc6845_device, screen_update)
	MCFG_PALETTE_ADD_MONOCHROME("palette")
	MCFG_DEVICE_ADD("gfxdecode", GFXDECODE, "palette", gfx_amust)

	/* sound hardware */
	SPEAKER(config, "mono").front_center();
	MCFG_DEVICE_ADD("beeper", BEEP, 800)
	MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50)

	/* Devices */
	MCFG_MC6845_ADD("crtc", H46505, "screen", XTAL(14'318'181) / 8)
	MCFG_MC6845_SHOW_BORDER_AREA(false)
	MCFG_MC6845_CHAR_WIDTH(8)
	MCFG_MC6845_UPDATE_ROW_CB(amust_state, crtc_update_row)

	MCFG_UPD765A_ADD("fdc", false, true)
	MCFG_FLOPPY_DRIVE_ADD("fdc:0", amust_floppies, "525qd", floppy_image_device::default_floppy_formats)
	MCFG_FLOPPY_DRIVE_SOUND(true)
	MCFG_FLOPPY_DRIVE_ADD("fdc:1", amust_floppies, "525qd", floppy_image_device::default_floppy_formats)
	MCFG_FLOPPY_DRIVE_SOUND(true)

	MCFG_DEVICE_ADD("uart_clock", CLOCK, 153600)
	MCFG_CLOCK_SIGNAL_HANDLER(WRITELINE("uart1", i8251_device, write_txc))
	MCFG_DEVCB_CHAIN_OUTPUT(WRITELINE("uart1", i8251_device, write_rxc))

	MCFG_DEVICE_ADD("uart1", I8251, 0)
	MCFG_I8251_TXD_HANDLER(WRITELINE("rs232", rs232_port_device, write_txd))
	MCFG_I8251_DTR_HANDLER(WRITELINE("rs232", rs232_port_device, write_dtr))
	MCFG_I8251_RTS_HANDLER(WRITELINE("rs232", rs232_port_device, write_rts))

	MCFG_DEVICE_ADD("rs232", RS232_PORT, default_rs232_devices, "keyboard")
	MCFG_RS232_RXD_HANDLER(WRITELINE("uart1", i8251_device, write_rxd))
	MCFG_RS232_CTS_HANDLER(WRITELINE("uart1", i8251_device, write_cts))
	MCFG_RS232_DSR_HANDLER(WRITELINE("uart1", i8251_device, write_dsr))

	MCFG_DEVICE_ADD("uart2", I8251, 0)
	//MCFG_I8251_TXD_HANDLER(WRITELINE("rs232", rs232_port_device, write_txd))
	//MCFG_I8251_DTR_HANDLER(WRITELINE("rs232", rs232_port_device, write_dtr))
	//MCFG_I8251_RTS_HANDLER(WRITELINE("rs232", rs232_port_device, write_rts))

	MCFG_DEVICE_ADD("pit", PIT8253, 0)

	MCFG_DEVICE_ADD("ppi1", I8255A, 0)
	MCFG_I8255_IN_PORTA_CB(READ8(*this, amust_state, port04_r))
	MCFG_I8255_OUT_PORTA_CB(WRITE8(*this, amust_state, port04_w))
	MCFG_I8255_IN_PORTB_CB(READ8(*this, amust_state, port05_r))
	MCFG_I8255_IN_PORTC_CB(READ8(*this, amust_state, port06_r))
	MCFG_I8255_OUT_PORTC_CB(WRITE8(*this, amust_state, port06_w))

	MCFG_DEVICE_ADD("ppi2", I8255A, 0)
	MCFG_I8255_IN_PORTA_CB(READ8(*this, amust_state, port08_r))
	MCFG_I8255_OUT_PORTA_CB(WRITE8(*this, amust_state, port08_w))
	MCFG_I8255_IN_PORTB_CB(READ8(*this, amust_state, port09_r))
	MCFG_I8255_IN_PORTC_CB(READ8(*this, amust_state, port0a_r))
	MCFG_I8255_OUT_PORTC_CB(WRITE8(*this, amust_state, port0a_w))
MACHINE_CONFIG_END

/* ROM definition */
ROM_START( amust )
	ROM_REGION( 0x11000, "maincpu", ROMREGION_ERASEFF )
	ROM_LOAD( "mon_h.rom", 0x10000, 0x1000, CRC(10dceac6) SHA1(1ef80039063f7a6455563d59f1bcc23e09eca369) )

	ROM_REGION( 0x800, "chargen", 0 )
	ROM_LOAD( "cg4.rom", 0x000, 0x800, CRC(52e7b9d8) SHA1(cc6d457634eb688ccef471f72bddf0424e64b045) )

	ROM_REGION( 0x800, "keyboard", 0 )
	ROM_LOAD( "kbd_3.rom", 0x000, 0x800, CRC(d9441b35) SHA1(ce250ab1e892a13fd75182703f259855388c6bf4) )

	ROM_REGION( 0x800, "videoram", ROMREGION_ERASE00 )
ROM_END

/* Driver */

//    YEAR  NAME   PARENT  COMPAT  MACHINE  INPUT  CLASS        INIT        COMPANY  FULLNAME               FLAGS
COMP( 1983, amust, 0,      0,      amust,   amust, amust_state, init_amust, "Amust", "Amust Executive 816", MACHINE_NOT_WORKING )