Translations of this page:

HowTo: Adding a MESS skeleton driver

This HowTo will teach you how to create a skeleton driver for MESS, the first step for your own driver.

For a very basic driver, we need to add one file (the actual driver) and modify two files, so that MESS knows about your driver.

Creating the driver

As an example, we'll create a driver for the hypothetical system “MX-1290” from Epson. Create a new file in mess/drivers and name it mx1290.c. Open this file and add the line

#include "driver.h"

Every driver includes this file. Now we basically need to add various macros to describe our system and functions that get called by the MAME/MESS core.

First, we add some functions:

static DRIVER_INIT(mx1290)
{
}

This function is called once at the beginning of the emulation. We don't need to put code in here now. Next, we'll add two functions for the video hardware:

static VIDEO_START( mx1290 )
{
}
 
static VIDEO_UPDATE( mx1290 )
{
    return 0;
}

Those get called at the start and when the graphics need updating.

static READ8_HANDLER( mx1290_port1_r )
{
    logerror("Read from port1 @%x\n", activecpu_get_pc());
    return 0xff;
}

An example READ8_HANDLER

static WRITE8_HANDLER( mx1290_port1_w )
{
    logerror("Write to port1 @%x: %02x\n", activecpu_get_pc(), data);
}

An example WRITE8_HANDLER

We will reference these two functions later in our address maps, which describe the memory layout of the system.

static ADDRESS_MAP_START(mx1290_mem, ADDRESS_SPACE_PROGRAM, 8)
    AM_RANGE( 0x0000, 0x0fff ) AM_ROM AM_REGION(REGION_CPU1, 0)
    AM_RANGE( 0x1000, 0x1fff ) AM_RAM
ADDRESS_MAP_END

The memory map of our system

static ADDRESS_MAP_START(mx1290_mem, ADDRESS_SPACE_IO, 8)
    ADDRESS_MAP_FLAGS( AMEF_ABITS(8) )
    AM_RANGE( 0x00, 0x0f ) AM_READWRITE( mx1290_port1_r, mx1290_port1_w )
ADDRESS_MAP_END

The I/O port map of our system

We have defined two ranges now in program memory now: A ROM region, where the firmware or BIOS is located, and a RAM region. We also added a map for the I/O ports, when the system writes or reads from the address 0x00 to 0x0f our READ8_HANDLER mx1290_port1_r and the WRITE8_HANDLER mx1290_port1_w are called. The read handler expects data from us, and the write handler will give us data.

We also need to define some input ports, i. e. Buttons etc. that the system has. This is done using a macro:

INPUT_PORTS_START( mx1290 )
INPUT_PORTS_END

Another macro finally describes the whole system:

static MACHINE_DRIVER_START( mx1290 )
    /* basic machine hardware */
    MDRV_CPU_ADD_TAG("main", Z80, MAIN_CLOCK / 4)
    MDRV_CPU_PROGRAM_MAP(mx1290_mem, 0)
    MDRV_CPU_IO_MAP(mx1290_io, 0)
 
    /* video hardware */
    MDRV_SCREEN_REFRESH_RATE(60)
    MDRV_SCREEN_VBLANK_TIME(DEFAULT_60HZ_VBLANK_DURATION)
    MDRV_VIDEO_ATTRIBUTES(VIDEO_TYPE_RASTER)
    MDRV_SCREEN_FORMAT(BITMAP_FORMAT_RGB32)
    MDRV_SCREEN_SIZE(640, 480)
    MDRV_SCREEN_VISIBLE_AREA(0, 639, 0, 479)
    MDRV_PALETTE_LENGTH(4)
 
    MDRV_VIDEO_START(mx1290)
    MDRV_VIDEO_UPDATE(mx1290)
MACHINE_DRIVER_END

A machine driver definition

This macro tells MESS what CPU our system uses and references our memory maps and video update functions. Note that we use a placeholder for the frequency our system runs at, this allows us to accurately describe how the clock is derived. For this to work, you need to #define MAIN_CLOCK 4000000 somewhere in an include file or at the top of the driver file. In our example, the real CPU clock would then be 1 MHz.

Finally, we can add some ROM loading macros.

ROM_START( mx1290 )
    ROM_REGION( 0x1000, REGION_CPU1, 0 )
    ROM_LOAD( "mx_v11.u22", 0x0000, 0x1000, CRC(6d84119d) SHA1(de60ead727b9317154742efd8e1206e9f9bb695b) )
ROM_END

A ROM loading definition

This macro creates a memory region with the size 0×1000 in REGION_CPU1 (that we referenced in our memory map) and loads one ROM with the filename mx_v11.u22 into this region at offset 0×0000, length 0×1000, CRC32 of 6d84119d and SHA1 of de60ead727b9317154742efd8e1206e9f9bb695b.

We are almost finished now, we only need some glue macro to combine everything above now. This is doing using either the COMP or CONS macros, which are used for computers and consoles respectively. Lets say this is a computer system, so we can add:

/*    YEAR  NAME   PARENT  COMPAT  MACHINE INPUT   INIT  CONFIG COMPANY  FULLNAME   FLAGS */
COMP( 1986, mx1290,     0,      0, mx1290, mx1290, NULL, NULL,  "Epson", "MX-1290", GAME_NO_SOUND | GAME_NOT_WORKING)

Name is the system name and used later when we add the actual driver to MESS. Machine is the MACHINE_DRIVER macro and Input are our input definitions.

The full driver now looks like this:

/* Epson MX-1290 driver by Anonymous */
 
#include "driver.h"
 
#define MAIN_CLOCK 4000000 /* 4 MHz */
 
/* Driver initialization */
static DRIVER_INIT(mx1290)
{
}
 
/* Video hardware */
static VIDEO_START( mx1290 )
{
}
 
static VIDEO_UPDATE( mx1290 )
{
    return 0;
}
 
/* Port 1 code */
static READ8_HANDLER( mx1290_port1_r )
{
    logerror("Read from port1 @%x\n", activecpu_get_pc());
    return 0xff;
}
 
static WRITE8_HANDLER( mx1290_port1_w )
{
    logerror("Write to port1 @%x: %02x\n", activecpu_get_pc(), data);
}
 
/* Address maps */
static ADDRESS_MAP_START(mx1290_mem, ADDRESS_SPACE_PROGRAM, 8)
    AM_RANGE( 0x0000, 0x0fff ) AM_ROM AM_REGION(REGION_CPU1, 0)
    AM_RANGE( 0x1000, 0x1fff ) AM_RAM
ADDRESS_MAP_END
 
static ADDRESS_MAP_START(mx1290_mem, ADDRESS_SPACE_IO, 8)
    ADDRESS_MAP_FLAGS( AMEF_ABITS(8) )
    AM_RANGE( 0x00, 0x0f ) AM_READWRITE( mx1290_port1_r, mx1290_port1_w )
ADDRESS_MAP_END
 
/* Input ports */
INPUT_PORTS_START( mx1290 )
INPUT_PORTS_END
 
/* Machine driver */
static MACHINE_DRIVER_START( mx1290 )
    /* basic machine hardware */
    MDRV_CPU_ADD_TAG("main", Z80, MAIN_CLOCK / 4)
    MDRV_CPU_PROGRAM_MAP(mx1290_mem, 0)
    MDRV_CPU_IO_MAP(mx1290_io, 0)
 
    /* video hardware */
    MDRV_SCREEN_REFRESH_RATE(60)
    MDRV_SCREEN_VBLANK_TIME(DEFAULT_60HZ_VBLANK_DURATION)
    MDRV_VIDEO_ATTRIBUTES(VIDEO_TYPE_RASTER)
    MDRV_SCREEN_FORMAT(BITMAP_FORMAT_RGB32)
    MDRV_SCREEN_SIZE(640, 480)
    MDRV_SCREEN_VISIBLE_AREA(0, 639, 0, 479)
    MDRV_PALETTE_LENGTH(4)
 
    MDRV_VIDEO_START(mx1290)
    MDRV_VIDEO_UPDATE(mx1290)
MACHINE_DRIVER_END
 
/* ROM definition */
ROM_START( mx1290 )
    ROM_REGION( 0x1000, REGION_CPU1, 0 )
    ROM_LOAD( "mx_v11.u22", 0x0000, 0x1000, CRC(6d84119d) SHA1(de60ead727b9317154742efd8e1206e9f9bb695b) )
ROM_END
 
/* Driver */
 
/*    YEAR  NAME   PARENT  COMPAT  MACHINE INPUT   INIT  CONFIG COMPANY  FULLNAME   FLAGS */
COMP( 1986, mx1290,     0,      0, mx1290, mx1290, NULL, NULL,  "Epson", "MX-1290", GAME_NO_SOUND | GAME_NOT_WORKING)

An example driver

Adding the driver

Adding the driver to MESS involves editing two files, mess/mess.mak and mess/messdriv.c.

mess.mak

Open the file and scroll to the section “manufacturer-specific groupings for drivers”. Look for the manufacturer of your emulated system. If you can't find it, add a new section. Lets add our system from Epson, our driver is called mx1290.c. Scroll down to the last manufacturer and add the following lines:

  $(MESSOBJ)/epson.a:	\
	$(MESS_DRIVERS)/mx1290.o

If the manufacturer already exists, just add the second line only.

messdriv.c

Open the file and scroll to an appropriate section (consoles are listed first, computers after that, grouped by manufacturer again). Add the following line:

DRIVER(mx1290)

Note that this is the system name that you specifid with the COMP or CONS macros and independent of the name of your source file.

Testing your new driver

Make a clean build (make -f makefile.mes DEBUG=1 clean) and compile MESS with make -f makefile.mes DEBUG=1. We enabled the debugger, because you can't really develop a driver without it. To run your new driver, type messd mx1290.

Further development

Note that usually the VIDEO_START and VIDEO_UPDATE functions will be moved into their own file in mess/video/mx1290.c and the READ/WRITE handlers are normally found in mess/machine/mx1290.c. The function prototypes for those will then be in a file called mess/includes/mx1290.h which is included into the main driver file.

howto/add_a_mess_skeleton_driver.txt · Last modified: 2007-08-31 14:29 by duke