/************************************************************************* ldcore.h Private core laserdisc player implementation. Copyright Nicola Salmoria and the MAME Team. Visit http://mamedev.org for licensing and usage restrictions. *************************************************************************/ #pragma once #ifndef __LDCORE_H__ #define __LDCORE_H__ #include "driver.h" #include "laserdsc.h" #include "vbiparse.h" /*************************************************************************** CONSTANTS ***************************************************************************/ /* common laserdisc states */ enum { LDSTATE_NONE, /* unspecified state */ LDSTATE_EJECTING, /* in the process of ejecting */ LDSTATE_EJECTED, /* fully ejected */ LDSTATE_PARKED, /* head parked in lead-in */ LDSTATE_LOADING, /* loading from ejected state */ LDSTATE_SPINUP, /* spinning up */ LDSTATE_PAUSING, /* looking for a frame boundary to pause */ LDSTATE_PAUSED, /* found a frame boundary; now paused */ /* parameter specifies the fieldnum of the first frame */ LDSTATE_PLAYING, /* playing forward normally, with audio */ /* parameter specifies the target frame, or 0 if none */ LDSTATE_PLAYING_SLOW_REVERSE, /* playing slow in the reverse direction, with no audio */ /* parameter specifies the number of times to repeat each track */ LDSTATE_PLAYING_SLOW_FORWARD, /* playing slow in the forward direction, with no audio */ /* parameter specifies the number of times to repeat each track */ LDSTATE_PLAYING_FAST_REVERSE, /* playing fast in the reverse direction, with no audio */ /* parameter specifies the number of frames to skip backwards after each frame */ LDSTATE_PLAYING_FAST_FORWARD, /* playing fast in the forward direction, with no audio */ /* parameter specifies the number of frames to skip forwards after each frame */ LDSTATE_STEPPING_REVERSE, /* single frame stepping in the reverse direction */ LDSTATE_STEPPING_FORWARD, /* single frame stepping in the forward direction */ LDSTATE_SCANNING, /* scanning in the forward or reverse direction */ /* parameter(0:7) controls how many vsyncs until revert to savestate */ /* parameter(8:31) specifies the speed */ LDSTATE_SEEKING, /* seeking to a specific frame */ /* parameter specifies the target frame */ LDSTATE_OTHER /* other states start here */ }; /* special frame and chapter numbers from VBI conversion */ #define FRAME_NOT_PRESENT -2 /* no frame number information present */ #define FRAME_LEAD_IN -1 /* lead-in code detected */ #define FRAME_LEAD_OUT 99999 /* lead-out code detected */ #define CHAPTER_NOT_PRESENT -2 /* no chapter number information present */ #define CHAPTER_LEAD_IN -1 /* lead-in code detected */ #define CHAPTER_LEAD_OUT 100 /* lead-out code detected */ /* generic head movement speeds; use player-specific information where appropriate */ #define GENERIC_SLOW_SPEED (5) /* 1/5 normal speed */ #define GENERIC_FAST_SPEED (3) /* 3x normal speed */ #define GENERIC_SCAN_SPEED (50) /* 50x normal speed */ #define GENERIC_SEARCH_SPEED (5000) /* 5000x normal speed */ /* generic timings; use player-specific information where appropriate */ #define GENERIC_EJECT_TIME (ATTOTIME_IN_SEC(5)) #define GENERIC_SPINUP_TIME (ATTOTIME_IN_SEC(2)) #define GENERIC_LOAD_TIME (ATTOTIME_IN_SEC(5)) /*************************************************************************** MACROS ***************************************************************************/ #define SCANNING_PARAM(speed,duration) (((speed) << 8) | ((duration) & 0xff)) /*************************************************************************** TYPE DEFINITIONS ***************************************************************************/ /* core-specific and player-specific data */ typedef struct _ldplayer_data ldplayer_data; typedef struct _ldcore_data ldcore_data; /* player state */ typedef struct _ldplayer_state ldplayer_state; struct _ldplayer_state { UINT8 state; /* current state */ INT32 substate; /* internal sub-state; starts at 0 on any state change */ INT32 param; /* parameter for current state */ attotime endtime; /* minimum ending time for current state */ }; /* generic data */ typedef struct _laserdisc_state laserdisc_state; struct _laserdisc_state { const device_config * device; /* pointer to owning device */ ldcore_data * core; /* private core data */ ldplayer_data * player; /* private player data */ ldplayer_state state; /* active state */ ldplayer_state savestate; /* saved state during temporary operations */ }; /* player-specific callbacks */ typedef void (*laserdisc_init_func)(laserdisc_state *ld); typedef INT32 (*laserdisc_update_func)(laserdisc_state *ld, const vbi_metadata *vbi, int fieldnum, attotime curtime); typedef void (*laserdisc_w_func)(laserdisc_state *ld, UINT8 prev, UINT8 new); typedef UINT8 (*laserdisc_r_func)(laserdisc_state *ld); /* player configuration */ typedef struct _ldplayer_interface ldplayer_interface; struct _ldplayer_interface { int type; /* type of the player */ size_t statesize; /* size of the state */ const char * name; /* name of the player */ laserdisc_init_func init; /* initialization callback */ laserdisc_update_func update; /* update callback */ laserdisc_w_func writedata; /* parallel data write */ laserdisc_w_func writeline[LASERDISC_INPUT_LINES]; /* single line write */ laserdisc_r_func readdata; /* parallel data read */ laserdisc_r_func readline[LASERDISC_OUTPUT_LINES]; /* single line read */ }; /*************************************************************************** GLOBAL VARIABLES ***************************************************************************/ /* defined by each player */ extern const ldplayer_interface pr7820_interface; extern const ldplayer_interface pr8210_interface; extern const ldplayer_interface simutrek_interface; extern const ldplayer_interface ldv1000_interface; extern const ldplayer_interface ldp1450_interface; extern const ldplayer_interface vp932_interface; /*************************************************************************** FUNCTION PROTOTYPES ***************************************************************************/ /* ----- player interface ----- */ /* return a token with type checking from a device */ laserdisc_state *ldcore_get_safe_token(const device_config *device); /* set the left/right audio squelch states */ void ldcore_set_audio_squelch(laserdisc_state *ld, UINT8 squelchleft, UINT8 squelchright); /* set the video squelch state */ void ldcore_set_video_squelch(laserdisc_state *ld, UINT8 squelch); /* ----- generic implementations ----- */ /* generically update in a way that works for most situations */ INT32 ldcore_generic_update(laserdisc_state *ld, const vbi_metadata *vbi, int fieldnum, attotime curtime, ldplayer_state *curstate); /*************************************************************************** INLINE FUNCTIONS ***************************************************************************/ /*------------------------------------------------- is_start_of_frame - return TRUE if this is the start of a frame -------------------------------------------------*/ INLINE int is_start_of_frame(const vbi_metadata *vbi) { /* is it not known if the white flag or the presence of a frame code determines the start of frame; the former seems to be the "official" way, but the latter seems to be the practical implementation */ return (vbi->white || (vbi->line1718 & 0xf80000) == 0xf80000); } /*------------------------------------------------- frame_from_metadata - return the frame number encoded in the metadata, if present, or FRAME_NOT_PRESENT -------------------------------------------------*/ INLINE int frame_from_metadata(const vbi_metadata *metadata) { UINT32 data; if ((metadata->line1718 & 0xf80000) == 0xf80000) data = metadata->line1718 & 0x7ffff; else if (metadata->line1718 == 0x88ffff) return FRAME_LEAD_IN; else if (metadata->line1718 == 0x80eeee) return FRAME_LEAD_OUT; else return FRAME_NOT_PRESENT; return (((data >> 16) & 0x0f) * 10000) + (((data >> 12) & 0x0f) * 1000) + (((data >> 8) & 0x0f) * 100) + (((data >> 4) & 0x0f) * 10) + (data & 0x0f); } /*------------------------------------------------- chapter_from_metadata - return the chapter number encoded in the metadata, if present, or CHAPTER_NOT_PRESENT -------------------------------------------------*/ INLINE int chapter_from_metadata(const vbi_metadata *metadata) { UINT32 data; if ((metadata->line1718 & 0xf00fff) == 0x800ddd) data = metadata->line1718 & 0x7f000; else if (metadata->line1718 == 0x88ffff) return CHAPTER_LEAD_IN; else if (metadata->line1718 == 0x80eeee) return CHAPTER_LEAD_OUT; else return CHAPTER_NOT_PRESENT; return (((data >> 16) & 0x0f) * 10) + ((data >> 12) & 0x0f); } #endif