summaryrefslogtreecommitdiffstatshomepage
path: root/trunk/src/emu/machine.h
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/src/emu/machine.h')
-rw-r--r--trunk/src/emu/machine.h624
1 files changed, 624 insertions, 0 deletions
diff --git a/trunk/src/emu/machine.h b/trunk/src/emu/machine.h
new file mode 100644
index 00000000000..01b2c665bd5
--- /dev/null
+++ b/trunk/src/emu/machine.h
@@ -0,0 +1,624 @@
+/***************************************************************************
+
+ machine.h
+
+ Controls execution of the core MAME system.
+
+****************************************************************************
+
+ Copyright Aaron Giles
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ * Neither the name 'MAME' nor the names of its contributors may be
+ used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+***************************************************************************/
+
+#pragma once
+
+#ifndef __EMU_H__
+#error Dont include this file directly; include emu.h instead.
+#endif
+
+#ifndef __MACHINE_H__
+#define __MACHINE_H__
+
+#include <time.h>
+
+
+
+//**************************************************************************
+// CONSTANTS
+//**************************************************************************
+
+const int MAX_GFX_ELEMENTS = 32;
+
+
+// machine phases
+enum machine_phase
+{
+ MACHINE_PHASE_PREINIT,
+ MACHINE_PHASE_INIT,
+ MACHINE_PHASE_RESET,
+ MACHINE_PHASE_RUNNING,
+ MACHINE_PHASE_EXIT
+};
+
+
+// notification callback types
+enum machine_notification
+{
+ MACHINE_NOTIFY_FRAME,
+ MACHINE_NOTIFY_RESET,
+ MACHINE_NOTIFY_PAUSE,
+ MACHINE_NOTIFY_RESUME,
+ MACHINE_NOTIFY_EXIT,
+ MACHINE_NOTIFY_COUNT
+};
+
+
+// output channels
+enum output_channel
+{
+ OUTPUT_CHANNEL_ERROR,
+ OUTPUT_CHANNEL_WARNING,
+ OUTPUT_CHANNEL_INFO,
+ OUTPUT_CHANNEL_DEBUG,
+ OUTPUT_CHANNEL_VERBOSE,
+ OUTPUT_CHANNEL_LOG,
+ OUTPUT_CHANNEL_COUNT
+};
+
+
+// debug flags
+const int DEBUG_FLAG_ENABLED = 0x00000001; // debugging is enabled
+const int DEBUG_FLAG_CALL_HOOK = 0x00000002; // CPU cores must call instruction hook
+const int DEBUG_FLAG_WPR_PROGRAM = 0x00000010; // watchpoints are enabled for PROGRAM memory reads
+const int DEBUG_FLAG_WPR_DATA = 0x00000020; // watchpoints are enabled for DATA memory reads
+const int DEBUG_FLAG_WPR_IO = 0x00000040; // watchpoints are enabled for IO memory reads
+const int DEBUG_FLAG_WPW_PROGRAM = 0x00000100; // watchpoints are enabled for PROGRAM memory writes
+const int DEBUG_FLAG_WPW_DATA = 0x00000200; // watchpoints are enabled for DATA memory writes
+const int DEBUG_FLAG_WPW_IO = 0x00000400; // watchpoints are enabled for IO memory writes
+const int DEBUG_FLAG_OSD_ENABLED = 0x00001000; // The OSD debugger is enabled
+
+
+
+//**************************************************************************
+// MACROS
+//**************************************************************************
+
+// macros to wrap legacy callbacks
+#define MACHINE_START_NAME(name) machine_start_##name
+#define MACHINE_START(name) void MACHINE_START_NAME(name)(running_machine &machine)
+#define MACHINE_START_CALL(name) MACHINE_START_NAME(name)(machine)
+
+#define MACHINE_RESET_NAME(name) machine_reset_##name
+#define MACHINE_RESET(name) void MACHINE_RESET_NAME(name)(running_machine &machine)
+#define MACHINE_RESET_CALL(name) MACHINE_RESET_NAME(name)(machine)
+
+#define SOUND_START_NAME(name) sound_start_##name
+#define SOUND_START(name) void SOUND_START_NAME(name)(running_machine &machine)
+#define SOUND_START_CALL(name) SOUND_START_NAME(name)(machine)
+
+#define SOUND_RESET_NAME(name) sound_reset_##name
+#define SOUND_RESET(name) void SOUND_RESET_NAME(name)(running_machine &machine)
+#define SOUND_RESET_CALL(name) SOUND_RESET_NAME(name)(machine)
+
+#define VIDEO_START_NAME(name) video_start_##name
+#define VIDEO_START(name) void VIDEO_START_NAME(name)(running_machine &machine)
+#define VIDEO_START_CALL(name) VIDEO_START_NAME(name)(machine)
+
+#define VIDEO_RESET_NAME(name) video_reset_##name
+#define VIDEO_RESET(name) void VIDEO_RESET_NAME(name)(running_machine &machine)
+#define VIDEO_RESET_CALL(name) VIDEO_RESET_NAME(name)(machine)
+
+#define PALETTE_INIT_NAME(name) palette_init_##name
+#define PALETTE_INIT(name) void PALETTE_INIT_NAME(name)(running_machine &machine, const UINT8 *color_prom)
+#define PALETTE_INIT_CALL(name) PALETTE_INIT_NAME(name)(machine, color_prom)
+
+
+
+// NULL versions
+#define machine_start_0 NULL
+#define machine_reset_0 NULL
+#define sound_start_0 NULL
+#define sound_reset_0 NULL
+#define video_start_0 NULL
+#define video_reset_0 NULL
+#define palette_init_0 NULL
+
+
+
+// global allocation helpers
+#define auto_alloc(m, t) pool_alloc(static_cast<running_machine &>(m).respool(), t)
+#define auto_alloc_clear(m, t) pool_alloc_clear(static_cast<running_machine &>(m).respool(), t)
+#define auto_alloc_array(m, t, c) pool_alloc_array(static_cast<running_machine &>(m).respool(), t, c)
+#define auto_alloc_array_clear(m, t, c) pool_alloc_array_clear(static_cast<running_machine &>(m).respool(), t, c)
+#define auto_free(m, v) pool_free(static_cast<running_machine &>(m).respool(), v)
+
+#define auto_bitmap_alloc(m, w, h, f) auto_alloc(m, bitmap_t(w, h, f))
+#define auto_strdup(m, s) strcpy(auto_alloc_array(m, char, strlen(s) + 1), s)
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// forward declarations
+class gfx_element;
+class colortable_t;
+class cheat_manager;
+class render_manager;
+class sound_manager;
+class video_manager;
+class debug_view_manager;
+class osd_interface;
+
+typedef struct _memory_private memory_private;
+typedef struct _palette_private palette_private;
+typedef struct _tilemap_private tilemap_private;
+typedef struct _romload_private romload_private;
+typedef struct _input_private input_private;
+typedef struct _input_port_private input_port_private;
+typedef struct _ui_input_private ui_input_private;
+typedef struct _debugcpu_private debugcpu_private;
+typedef struct _generic_machine_private generic_machine_private;
+typedef struct _generic_video_private generic_video_private;
+typedef struct _generic_audio_private generic_audio_private;
+
+
+// legacy callback functions
+typedef void (*legacy_callback_func)(running_machine &machine);
+typedef void (*palette_init_func)(running_machine &machine, const UINT8 *color_prom);
+
+
+
+// ======================> memory_region
+
+// memory region object; should eventually be renamed memory_region
+class memory_region
+{
+ DISABLE_COPYING(memory_region);
+
+ friend class running_machine;
+ friend class simple_list<memory_region>;
+ friend resource_pool_object<memory_region>::~resource_pool_object();
+
+ // construction/destruction
+ memory_region(running_machine &machine, const char *name, UINT32 length, UINT8 width, endianness_t endian);
+ ~memory_region();
+
+public:
+ // getters
+ running_machine &machine() const { return m_machine; }
+ memory_region *next() const { return m_next; }
+ UINT8 *base() const { return (this != NULL) ? m_base.u8 : NULL; }
+ UINT8 *end() const { return (this != NULL) ? m_base.u8 + m_length : NULL; }
+ UINT32 bytes() const { return (this != NULL) ? m_length : 0; }
+ const char *name() const { return m_name; }
+
+ // flag expansion
+ endianness_t endianness() const { return m_endianness; }
+ UINT8 width() const { return m_width; }
+
+ // data access
+ UINT8 &u8(offs_t offset = 0) const { return m_base.u8[offset]; }
+ UINT16 &u16(offs_t offset = 0) const { return m_base.u16[offset]; }
+ UINT32 &u32(offs_t offset = 0) const { return m_base.u32[offset]; }
+ UINT64 &u64(offs_t offset = 0) const { return m_base.u64[offset]; }
+
+ // allow passing a region for any common pointer
+ operator void *() const { return (this != NULL) ? m_base.v : NULL; }
+ operator INT8 *() const { return (this != NULL) ? m_base.i8 : NULL; }
+ operator UINT8 *() const { return (this != NULL) ? m_base.u8 : NULL; }
+ operator INT16 *() const { return (this != NULL) ? m_base.i16 : NULL; }
+ operator UINT16 *() const { return (this != NULL) ? m_base.u16 : NULL; }
+ operator INT32 *() const { return (this != NULL) ? m_base.i32 : NULL; }
+ operator UINT32 *() const { return (this != NULL) ? m_base.u32 : NULL; }
+ operator INT64 *() const { return (this != NULL) ? m_base.i64 : NULL; }
+ operator UINT64 *() const { return (this != NULL) ? m_base.u64 : NULL; }
+
+private:
+ // internal data
+ running_machine & m_machine;
+ memory_region * m_next;
+ astring m_name;
+ generic_ptr m_base;
+ UINT32 m_length;
+ UINT8 m_width;
+ endianness_t m_endianness;
+};
+
+
+
+// ======================> generic_pointers
+
+// holds generic pointers that are commonly used
+struct generic_pointers
+{
+ generic_ptr spriteram; // spriteram
+ UINT32 spriteram_size;
+ generic_ptr spriteram2; // secondary spriteram
+ UINT32 spriteram2_size;
+ generic_ptr buffered_spriteram; // buffered spriteram
+ generic_ptr buffered_spriteram2;// secondary buffered spriteram
+ generic_ptr paletteram; // palette RAM
+ generic_ptr paletteram2; // secondary palette RAM
+ bitmap_t * tmpbitmap; // temporary bitmap
+};
+
+
+
+// ======================> system_time
+
+// system time description, both local and UTC
+class system_time
+{
+public:
+ system_time();
+ void set(time_t t);
+
+ struct full_time
+ {
+ void set(struct tm &t);
+
+ UINT8 second; // seconds (0-59)
+ UINT8 minute; // minutes (0-59)
+ UINT8 hour; // hours (0-23)
+ UINT8 mday; // day of month (1-31)
+ UINT8 month; // month (0-11)
+ INT32 year; // year (1=1 AD)
+ UINT8 weekday; // day of week (0-6)
+ UINT16 day; // day of year (0-365)
+ UINT8 is_dst; // is this daylight savings?
+ };
+
+ INT64 time; // number of seconds elapsed since midnight, January 1 1970 UTC
+ full_time local_time; // local time
+ full_time utc_time; // UTC coordinated time
+};
+
+
+
+// ======================> running_machine
+
+typedef delegate<void ()> machine_notify_delegate;
+
+// description of the currently-running machine
+class running_machine
+{
+ DISABLE_COPYING(running_machine);
+
+ friend void debugger_init(running_machine &machine);
+ friend class sound_manager;
+
+ typedef void (*logerror_callback)(running_machine &machine, const char *string);
+
+ // must be at top of member variables
+ resource_pool m_respool; // pool of resources for this machine
+
+public:
+ // construction/destruction
+ running_machine(const machine_config &config, osd_interface &osd, bool exit_to_game_select = false);
+ ~running_machine();
+
+ // getters
+ const machine_config &config() const { return m_config; }
+ const device_list &devicelist() const { return m_config.devicelist(); }
+ const game_driver &system() const { return m_system; }
+ osd_interface &osd() const { return m_osd; }
+ resource_pool &respool() { return m_respool; }
+ device_scheduler &scheduler() { return m_scheduler; }
+ save_manager &save() { return m_save; }
+ cheat_manager &cheat() const { assert(m_cheat != NULL); return *m_cheat; }
+ render_manager &render() const { assert(m_render != NULL); return *m_render; }
+ input_manager &input() const { assert(m_input != NULL); return *m_input; }
+ sound_manager &sound() const { assert(m_sound != NULL); return *m_sound; }
+ video_manager &video() const { assert(m_video != NULL); return *m_video; }
+ debug_view_manager &debug_view() const { assert(m_debug_view != NULL); return *m_debug_view; }
+ driver_device *driver_data() const { return m_driver_device; }
+ template<class _DriverClass> _DriverClass *driver_data() const { return downcast<_DriverClass *>(m_driver_device); }
+ machine_phase phase() const { return m_current_phase; }
+ bool paused() const { return m_paused || (m_current_phase != MACHINE_PHASE_RUNNING); }
+ bool exit_pending() const { return m_exit_pending; }
+ bool new_driver_pending() const { return (m_new_driver_pending != NULL); }
+ const char *new_driver_name() const { return m_new_driver_pending->name; }
+ bool ui_active() const { return m_ui_active; }
+ const char *basename() const { return m_basename; }
+ int sample_rate() const { return m_sample_rate; }
+ bool save_or_load_pending() const { return m_saveload_pending_file; }
+ screen_device *first_screen() const { return primary_screen; }
+
+ // additional helpers
+ emu_options &options() const { return m_config.options(); }
+ memory_region *first_region() const { return m_regionlist.first(); }
+ attotime time() const { return m_scheduler.time(); }
+ bool scheduled_event_pending() const { return m_exit_pending || m_hard_reset_pending; }
+
+ // fetch items by name
+ inline device_t *device(const char *tag);
+ template<class _DeviceClass> inline _DeviceClass *device(const char *tag) { return downcast<_DeviceClass *>(device(tag)); }
+ inline const input_port_config *port(const char *tag);
+ inline const memory_region *region(const char *tag);
+
+ // configuration helpers
+ device_t &add_dynamic_device(device_t &owner, device_type type, const char *tag, UINT32 clock);
+ UINT32 total_colors() const { return m_config.m_total_colors; }
+
+ // immediate operations
+ int run(bool firstrun);
+ void pause();
+ void resume();
+ void add_notifier(machine_notification event, machine_notify_delegate callback);
+ void call_notifiers(machine_notification which);
+ void add_logerror_callback(logerror_callback callback);
+ void set_ui_active(bool active) { m_ui_active = active; }
+
+ // scheduled operations
+ void schedule_exit();
+ void schedule_hard_reset();
+ void schedule_soft_reset();
+ void schedule_new_driver(const game_driver &driver);
+ void schedule_save(const char *filename);
+ void schedule_load(const char *filename);
+
+ // date & time
+ void base_datetime(system_time &systime);
+ void current_datetime(system_time &systime);
+
+ // regions
+ memory_region *region_alloc(const char *name, UINT32 length, UINT8 width, endianness_t endian);
+ void region_free(const char *name);
+
+ // misc
+ void CLIB_DECL logerror(const char *format, ...);
+ void CLIB_DECL vlogerror(const char *format, va_list args);
+ UINT32 rand();
+ const char *describe_context();
+
+ // internals
+ ioport_list m_portlist; // points to a list of input port configurations
+
+ // CPU information
+ cpu_device * firstcpu; // first CPU (allows for quick iteration via typenext)
+
+ // video-related information
+ gfx_element * gfx[MAX_GFX_ELEMENTS];// array of pointers to graphic sets (chars, sprites)
+ screen_device * primary_screen; // the primary screen device, or NULL if screenless
+ palette_t * palette; // global palette object
+
+ // palette-related information
+ const pen_t * pens; // remapped palette pen numbers
+ colortable_t * colortable; // global colortable for remapping
+ pen_t * shadow_table; // table for looking up a shadowed pen
+ bitmap_t * priority_bitmap; // priority bitmap
+
+ // debugger-related information
+ UINT32 debug_flags; // the current debug flags
+
+ // generic pointers
+ generic_pointers generic; // generic pointers
+
+ // internal core information
+ memory_private * memory_data; // internal data from memory.c
+ palette_private * palette_data; // internal data from palette.c
+ tilemap_private * tilemap_data; // internal data from tilemap.c
+ romload_private * romload_data; // internal data from romload.c
+ input_private * input_data; // internal data from input.c
+ input_port_private * input_port_data; // internal data from inptport.c
+ ui_input_private * ui_input_data; // internal data from uiinput.c
+ debugcpu_private * debugcpu_data; // internal data from debugcpu.c
+ generic_machine_private *generic_machine_data; // internal data from machine/generic.c
+ generic_video_private * generic_video_data; // internal data from video/generic.c
+ generic_audio_private * generic_audio_data; // internal data from audio/generic.c
+
+private:
+ // internal helpers
+ void start();
+ void set_saveload_filename(const char *filename);
+ void fill_systime(system_time &systime, time_t t);
+ void handle_saveload();
+ void soft_reset(void *ptr = NULL, INT32 param = 0);
+
+ // internal callbacks
+ static void logfile_callback(running_machine &machine, const char *buffer);
+
+ // internal state
+ const machine_config & m_config; // reference to the constructed machine_config
+ const game_driver & m_system; // reference to the definition of the game machine
+ osd_interface & m_osd; // reference to OSD system
+
+ // embedded managers and objects
+ tagged_list<memory_region> m_regionlist; // list of memory regions
+ save_manager m_save; // save manager
+ device_scheduler m_scheduler; // scheduler object
+
+ // managers
+ cheat_manager * m_cheat; // internal data from cheat.c
+ render_manager * m_render; // internal data from render.c
+ input_manager * m_input; // internal data from input.c
+ sound_manager * m_sound; // internal data from sound.c
+ video_manager * m_video; // internal data from video.c
+ debug_view_manager * m_debug_view; // internal data from debugvw.c
+
+ // driver state
+ driver_device * m_driver_device; // pointer to the current driver device
+
+ // system state
+ machine_phase m_current_phase; // current execution phase
+ bool m_paused; // paused?
+ bool m_hard_reset_pending; // is a hard reset pending?
+ bool m_exit_pending; // is an exit pending?
+ bool m_exit_to_game_select; // when we exit, go we go back to the game select?
+ const game_driver * m_new_driver_pending; // pointer to the next pending driver
+ emu_timer * m_soft_reset_timer; // timer used to schedule a soft reset
+
+ // misc state
+ UINT32 m_rand_seed; // current random number seed
+ bool m_ui_active; // ui active or not (useful for games / systems with keyboard inputs)
+ time_t m_base_time; // real time at initial emulation time
+ astring m_basename; // basename used for game-related paths
+ astring m_context; // context string buffer
+ int m_sample_rate; // the digital audio sample rate
+ emu_file * m_logfile; // pointer to the active log file
+
+ // load/save management
+ enum saveload_schedule
+ {
+ SLS_NONE,
+ SLS_SAVE,
+ SLS_LOAD
+ };
+ saveload_schedule m_saveload_schedule;
+ attotime m_saveload_schedule_time;
+ astring m_saveload_pending_file;
+ const char * m_saveload_searchpath;
+
+ // notifier callbacks
+ struct notifier_callback_item
+ {
+ // construction/destruction
+ notifier_callback_item(machine_notify_delegate func);
+
+ // getters
+ notifier_callback_item *next() const { return m_next; }
+
+ // state
+ notifier_callback_item * m_next;
+ machine_notify_delegate m_func;
+ };
+ simple_list<notifier_callback_item> m_notifier_list[MACHINE_NOTIFY_COUNT];
+
+ // logerror callbacks
+ class logerror_callback_item
+ {
+ public:
+ // construction/destruction
+ logerror_callback_item(logerror_callback func);
+
+ // getters
+ logerror_callback_item *next() const { return m_next; }
+
+ // state
+ logerror_callback_item * m_next;
+ logerror_callback m_func;
+ };
+ simple_list<logerror_callback_item> m_logerror_list;
+};
+
+
+
+// ======================> driver_device
+
+// base class for machine driver-specific devices
+class driver_device : public device_t
+{
+public:
+ // construction/destruction
+ driver_device(const machine_config &mconfig, device_type type, const char *tag);
+ virtual ~driver_device();
+
+ // indexes into our generic callbacks
+ enum callback_type
+ {
+ CB_MACHINE_START,
+ CB_MACHINE_RESET,
+ CB_SOUND_START,
+ CB_SOUND_RESET,
+ CB_VIDEO_START,
+ CB_VIDEO_RESET,
+ CB_COUNT
+ };
+
+ // inline configuration helpers
+ static void static_set_game(device_t &device, const game_driver &game);
+ static void static_set_callback(device_t &device, callback_type type, legacy_callback_func callback);
+ static void static_set_palette_init(device_t &device, palette_init_func callback);
+
+ // additional video helpers
+ virtual bool screen_update(screen_device &screen, bitmap_t &bitmap, const rectangle &cliprect);
+ virtual void screen_eof();
+
+protected:
+ // helpers called at startup
+ virtual void driver_start();
+ virtual void machine_start();
+ virtual void sound_start();
+ virtual void video_start();
+
+ // helpers called at reset
+ virtual void driver_reset();
+ virtual void machine_reset();
+ virtual void sound_reset();
+ virtual void video_reset();
+
+ // device-level overrides
+ virtual const rom_entry *device_rom_region() const;
+ virtual ioport_constructor device_input_ports() const;
+ virtual void device_start();
+ virtual void device_reset();
+
+ // internal state
+ const game_driver * m_system; // pointer to the game driver
+
+ legacy_callback_func m_callbacks[CB_COUNT]; // generic legacy callbacks
+ palette_init_func m_palette_init; // one-time palette init callback
+};
+
+
+// this template function creates a stub which constructs a device
+template<class _DriverClass>
+device_t *driver_device_creator(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+{
+ assert(owner == NULL);
+ assert(clock == 0);
+ return global_alloc_clear(_DriverClass(mconfig, &driver_device_creator<_DriverClass>, tag));
+}
+
+
+
+//**************************************************************************
+// INLINE FUNCTIONS
+//**************************************************************************
+
+inline device_t *running_machine::device(const char *tag)
+{
+ return devicelist().find(tag);
+}
+
+inline const input_port_config *running_machine::port(const char *tag)
+{
+ return m_portlist.find(tag);
+}
+
+inline const memory_region *running_machine::region(const char *tag)
+{
+ return m_regionlist.find(tag);
+}
+
+
+#endif /* __MACHINE_H__ */