summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Aaron Giles <aaron@aarongiles.com>2008-08-18 04:31:08 +0000
committer Aaron Giles <aaron@aarongiles.com>2008-08-18 04:31:08 +0000
commit284b5a0d95c4740b25fd1d06aecd2cc74eae12f3 (patch)
treeed984f6362decda13c57c168d5d2d18d6e30d06c
parentd0eb89399fc684c90330466674470775079ae113 (diff)
Added new generic laserdisc VIDEO_UPDATE handler to the laserdisc code.
This handler works for both disc-only games and those with overlays. For disc-only games, the base macro is sufficient. For games with overlays, an additional set of configuration macros are provided: MDRV_LASERDISC_OVERLAY - specifies update function, width, height, and bitmap format of the overlay MDRV_LASERDISC_OVERLAY_CLIP - specifies the visible area of the overlay bitmap MDRV_LASERDISC_OVERLAY_POSITION - specifies default x,y position MDRV_LASERDISC_OVERLAY_SCALE - specifies default x,y scale factors The update function provided to MDRV_LASERDISC_OVERLAY is identical to a normal VIDEO_UPDATE callback, so a standard one can be used. All existing laserdisc drivers have been updated to support this new rendering mechanism, removing much duplicated code. Added the ability to configure the overlay position and scale parameters at runtime. Added OSD menus to control them. Added logic to save/restore the data in the game's configuration file. Added new macros MDRV_LASERDISC_SCREEN_ADD_NTSC and _PAL, which defines a standard screen with the correct video timing characteristics and update function for laserdiscs. Updated all drivers to use these macros instead of defining their own screens. Added DISK_REGIONS to all laserdisc drivers. Added DISK_IMAGE_READONLY_OPTIONAL to support games (like Cube Quest) where the disk is non-essential to the game's operation. Fixed bug in identifying the custom sound driver for the laserdisc. Updated ldverify to identify blank regions of the disc for post- processing. Fixed rendering 16bpp with alpha using bilinear filters (fixes screenshots of laserdisc games with overlays). Included support for parsing .gdi files in chdman. [ElSemi] Added new driver for Cube Quest. This includes CPU cores for the three bitslice processors, as well as laserdisc support for the hacked laserdisc that was used to drive the games. [Philip Bennett, Joe Magiera, Warren Ondras] Note that the SHA1/MD5 for the laserdisc will likely undergo at least one more change before being finalized.
-rw-r--r--.gitattributes3
-rw-r--r--src/emu/cpu/cpu.mak16
-rw-r--r--src/emu/cpu/cubeqcpu/cubeqcpu.c2194
-rw-r--r--src/emu/cpu/cubeqcpu/cubeqcpu.h146
-rw-r--r--src/emu/cpuexec.h3
-rw-r--r--src/emu/cpuintrf.c8
-rw-r--r--src/emu/machine/laserdsc.c550
-rw-r--r--src/emu/machine/laserdsc.h85
-rw-r--r--src/emu/rendersw.c48
-rw-r--r--src/emu/romload.c2
-rw-r--r--src/emu/romload.h2
-rw-r--r--src/emu/ui.c140
-rw-r--r--src/ldplayer/ldplayer.c48
-rw-r--r--src/lib/util/avcomp.c6
-rw-r--r--src/mame/drivers/alg.c84
-rw-r--r--src/mame/drivers/cliffhgr.c68
-rw-r--r--src/mame/drivers/cubeqst.c700
-rw-r--r--src/mame/drivers/dlair.c102
-rw-r--r--src/mame/drivers/esh.c28
-rw-r--r--src/mame/drivers/gottlieb.c12
-rw-r--r--src/mame/drivers/gpworld.c22
-rw-r--r--src/mame/drivers/istellar.c25
-rw-r--r--src/mame/drivers/lgp.c23
-rw-r--r--src/mame/drivers/segald.c35
-rw-r--r--src/mame/drivers/superdq.c55
-rw-r--r--src/mame/drivers/thayers.c18
-rw-r--r--src/mame/includes/gottlieb.h2
-rw-r--r--src/mame/mame.mak2
-rw-r--r--src/mame/mamedriv.c1
-rw-r--r--src/mame/video/gottlieb.c62
-rw-r--r--src/tools/chdcd.c114
-rw-r--r--src/tools/chdman.c4
-rw-r--r--src/tools/ldverify.c79
33 files changed, 4166 insertions, 521 deletions
diff --git a/.gitattributes b/.gitattributes
index 1a93b3718af..2dd112589f4 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -60,6 +60,8 @@ src/emu/cpu/cp1610/1610dasm.c svneol=native#text/plain
src/emu/cpu/cp1610/cp1610.c svneol=native#text/plain
src/emu/cpu/cp1610/cp1610.h svneol=native#text/plain
src/emu/cpu/cpu.mak svneol=native#text/plain
+src/emu/cpu/cubeqcpu/cubeqcpu.c svneol=native#text/plain
+src/emu/cpu/cubeqcpu/cubeqcpu.h svneol=native#text/plain
src/emu/cpu/drcbec.c svneol=native#text/plain
src/emu/cpu/drcbeut.c svneol=native#text/plain
src/emu/cpu/drcbeut.h svneol=native#text/plain
@@ -1367,6 +1369,7 @@ src/mame/drivers/crshrace.c svneol=native#text/plain
src/mame/drivers/crystal.c svneol=native#text/plain
src/mame/drivers/cshooter.c svneol=native#text/plain
src/mame/drivers/csk.c svneol=native#text/plain
+src/mame/drivers/cubeqst.c svneol=native#text/plain
src/mame/drivers/cubocd32.c svneol=native#text/plain
src/mame/drivers/cultures.c svneol=native#text/plain
src/mame/drivers/cvs.c svneol=native#text/plain
diff --git a/src/emu/cpu/cpu.mak b/src/emu/cpu/cpu.mak
index 5470a74ab83..f5f551deffd 100644
--- a/src/emu/cpu/cpu.mak
+++ b/src/emu/cpu/cpu.mak
@@ -254,6 +254,22 @@ $(CPUOBJ)/jaguar/jaguar.o: $(CPUSRC)/jaguar/jaguar.c \
#-------------------------------------------------
+# Simutrek Cube Quest bit-sliced CPUs
+#-------------------------------------------------
+CPUDEFS += -DHAS_CUBEQCPU=$(if $(filter CUBEQCPU,$(CPUS)),1,0)
+
+ifneq ($(filter CUBEQCPU,$(CPUS)),)
+OBJDIRS += $(CPUOBJ)/cubeqcpu
+CPUOBJS += $(CPUOBJ)/cubeqcpu/cubeqcpu.o
+#DBGOBJS += $(CPUOBJ)/cubeqcpu/cubedasm.o
+endif
+
+$(CPUOBJ)/cubeqcpu/cubeqcpu.o: $(CPUSRC)/cubeqcpu/cubeqcpu.c \
+ $(CPUSRC)/cubeqcpu/cubeqcpu.h
+
+
+
+#-------------------------------------------------
# RCA CDP1802
#-------------------------------------------------
diff --git a/src/emu/cpu/cubeqcpu/cubeqcpu.c b/src/emu/cpu/cubeqcpu/cubeqcpu.c
new file mode 100644
index 00000000000..dcffe8b65dd
--- /dev/null
+++ b/src/emu/cpu/cubeqcpu/cubeqcpu.c
@@ -0,0 +1,2194 @@
+/***************************************************************************
+
+ cubeqcpu.c
+
+ Implementation of the Cube Quest AM2901-based CPUs
+
+ TODO:
+
+ * Tidy up diassembly (split into different files?)
+
+***************************************************************************/
+
+#include "debugger.h"
+#include "cubeqcpu.h"
+
+
+/***************************************************************************
+ CONSTANTS
+***************************************************************************/
+
+/* Am2901 Instruction Fields */
+static const char* ins[] =
+{
+ "ADD ",
+ "SUBR ",
+ "SUBS ",
+ "OR ",
+ "AND ",
+ "NOTRS",
+ "EXOR ",
+ "EXNOR",
+};
+
+static const char* src[] =
+{
+ "A,Q",
+ "A,B",
+ "0,Q",
+ "0,B",
+ "0,A",
+ "D,A",
+ "D,Q",
+ "D,0",
+};
+
+static const char* dst[] =
+{
+ "QREG ",
+ "NOP ",
+ "RAMA ",
+ "RAMF ",
+ "RAMQD",
+ "RAMD ",
+ "RAMQU",
+ "RAMU ",
+};
+
+enum
+{
+ AQ = 0,
+ AB = 1,
+ ZQ = 2,
+ ZB = 3,
+ ZA = 4,
+ DA = 5,
+ DQ = 6,
+ DZ = 7,
+} alu_src;
+
+enum
+{
+ ADD = 0,
+ SUBR = 1,
+ SUBS = 2,
+ OR = 3,
+ AND = 4,
+ NOTRS = 5,
+ EXOR = 6,
+ EXNOR = 7,
+} alu_ins;
+
+enum
+{
+ QREG = 0,
+ NOP = 1,
+ RAMA = 2,
+ RAMF = 3,
+ RAMQD = 4,
+ RAMD = 5,
+ RAMQU = 6,
+ RAMU = 7,
+} alu_dest;
+
+/***************************************************************************
+ MACROS
+***************************************************************************/
+
+#define _BIT(x, n) ((x) & (1 << (n)))
+
+/***************************************************************************
+ STRUCTURES & TYPEDEFS
+***************************************************************************/
+
+typedef struct
+{
+ /* AM2901 internals */
+ UINT16 ram[16];
+ UINT16 q;
+ UINT16 f;
+ UINT16 y;
+ UINT32 cflag;
+ UINT32 vflag;
+
+ UINT8 pc; /* 2 x LS161 @ 6E, 6F */
+ UINT16 platch;
+ UINT8 rtnlatch; /* LS374 @ 5F */
+ UINT8 adrcntr; /* 2 x LS161 */
+ UINT16 adrlatch;
+ UINT16 dinlatch;
+ UINT16 ramwlatch;
+
+ UINT16 *sram;
+
+ int prev_ipram;
+ int prev_ipwrt;
+
+ void (*dac_w)(UINT16 data);
+ UINT16 *sound_data;
+} cquestsnd_state;
+
+
+typedef struct
+{
+ /* AM2901 internals */
+ UINT16 ram[16];
+ UINT16 q;
+ UINT16 f;
+ UINT16 y;
+ UINT32 cflag;
+ UINT32 vflag;
+
+ UINT16 pc; /* 12-bit, but only 9 used */
+ UINT8 seqcnt; /* 4-bit counter */
+
+ UINT8 dsrclatch;
+ UINT8 rsrclatch;
+ UINT16 dynaddr; /* LS374 at 2D, 8D */
+ UINT16 dyndata; /* LS374 at 10B, 9B */
+ UINT16 yrlatch; /* LS374 at 9D, 10D */
+ UINT16 ydlatch; /* LS374 at 9C, 10C */
+ UINT16 dinlatch;
+ UINT8 divreg; /* LS74 at ? */
+
+ UINT16 linedata;
+ UINT16 lineaddr;
+
+ UINT16 *dram;
+ UINT16 *sram;
+
+ UINT8 prev_dred;
+ UINT8 prev_dwrt;
+ UINT8 wc;
+ UINT8 rc;
+ UINT8 clkcnt;
+} cquestrot_state;
+
+
+typedef struct
+{
+ /* 12-bit AM2901 internals */
+ UINT16 ram[16];
+ UINT16 q;
+ UINT16 f;
+ UINT16 y;
+ UINT32 cflag;
+ UINT32 vflag;
+
+ UINT8 pc[2]; /* Two program counters; one for FG, other for BG */
+
+ UINT16 seqcnt; /* 12-bit */
+ UINT16 clatch; /* LS374 at 9E and 1-bit FF */
+ UINT8 zlatch; /* LS374 at 4H */
+
+ UINT16 xcnt;
+ UINT16 ycnt;
+ UINT8 sreg;
+
+ UINT16 fadlatch;
+ UINT16 badlatch;
+
+ UINT16 sramdlatch;
+
+ UINT8 fglatch;
+ UINT8 bglatch;
+ UINT8 gt0reg;
+ UINT8 fdxreg;
+ UINT32 field;
+
+ UINT32 clkcnt;
+
+ /* RAM */
+ UINT16 *sram;
+ UINT8 *ptr_ram;
+ UINT32 *e_stack;
+ UINT32 *o_stack;
+
+} cquestlin_state;
+
+/***************************************************************************
+ PUBLIC GLOBAL VARIABLES
+***************************************************************************/
+
+static int cquestsnd_icount;
+static int cquestrot_icount;
+static int cquestlin_icount;
+
+/***************************************************************************
+ PRIVATE GLOBAL VARIABLES
+***************************************************************************/
+
+static cquestsnd_state cquestsnd;
+static cquestrot_state cquestrot;
+static cquestlin_state cquestlin;
+
+/***************************************************************************
+ MEMORY ACCESSORS FOR 68000
+***************************************************************************/
+
+WRITE16_HANDLER( write_sndram )
+{
+ COMBINE_DATA(&cquestsnd.sram[offset]);
+}
+
+READ16_HANDLER( read_sndram )
+{
+ return cquestsnd.sram[offset];
+}
+
+
+WRITE16_HANDLER( write_rotram )
+{
+ COMBINE_DATA(&cquestrot.dram[offset]);
+}
+
+READ16_HANDLER( read_rotram )
+{
+ return cquestrot.dram[offset];
+}
+
+/***************************************************************************
+ INLINE FUNCTIONS
+***************************************************************************/
+
+
+/***************************************************************************
+ CONTEXT SWITCHING
+***************************************************************************/
+
+static void cquestsnd_get_context(void *dst)
+{
+ /* Copy the context */
+ if (dst)
+ *(cquestsnd_state *)dst = cquestsnd;
+}
+
+
+static void cquestsnd_set_context(void *src)
+{
+ /* Copy the context */
+ if (src)
+ cquestsnd = *(cquestsnd_state *)src;
+}
+
+
+static void cquestrot_get_context(void *dst)
+{
+ /* Copy the context */
+ if (dst)
+ *(cquestrot_state *)dst = cquestrot;
+}
+
+
+static void cquestrot_set_context(void *src)
+{
+ /* Copy the context */
+ if (src)
+ cquestrot = *(cquestrot_state *)src;
+}
+
+
+static void cquestlin_get_context(void *dst)
+{
+ /* Copy the context */
+ if (dst)
+ *(cquestlin_state *)dst = cquestlin;
+}
+
+
+static void cquestlin_set_context(void *src)
+{
+ /* Copy the context */
+ if (src)
+ cquestlin = *(cquestlin_state *)src;
+}
+
+/***************************************************************************
+ SOUND INITIALIZATION AND SHUTDOWN
+***************************************************************************/
+
+static STATE_POSTLOAD( cquestsnd_postload )
+{
+
+}
+
+static void cquestsnd_state_register(int index, const char *type)
+{
+ state_save_register_item_array(type, index, cquestsnd.ram);
+ state_save_register_item(type, index, cquestsnd.q);
+ state_save_register_item(type, index, cquestsnd.f);
+ state_save_register_item(type, index, cquestsnd.y);
+ state_save_register_item(type, index, cquestsnd.cflag);
+ state_save_register_item(type, index, cquestsnd.vflag);
+
+ state_save_register_item(type, index, cquestsnd.pc);
+ state_save_register_item(type, index, cquestsnd.platch);
+ state_save_register_item(type, index, cquestsnd.rtnlatch);
+ state_save_register_item(type, index, cquestsnd.adrcntr);
+ state_save_register_item(type, index, cquestsnd.adrlatch);
+ state_save_register_item(type, index, cquestsnd.dinlatch);
+ state_save_register_item(type, index, cquestsnd.ramwlatch);
+ state_save_register_item(type, index, cquestsnd.prev_ipram);
+ state_save_register_item(type, index, cquestsnd.prev_ipwrt);
+
+ state_save_register_postload(Machine, cquestsnd_postload, NULL);
+}
+
+static void cquestsnd_init(int index, int clock, const void *config, int (*irqcallback)(int))
+{
+ cubeqst_snd_config* _config = (cubeqst_snd_config*)config;
+
+ memset(&cquestsnd, 0, sizeof(cquestsnd));
+
+ cquestsnd_state_register(index, "cquestsnd");
+
+ cquestsnd.dac_w = _config->dac_w;
+ cquestsnd.sound_data = (UINT16*)memory_region(Machine, _config->sound_data_region);
+
+ /* Allocate RAM shared with 68000 */
+ cquestsnd.sram = malloc(4096);
+}
+
+
+static void cquestsnd_reset(void)
+{
+ cquestsnd.pc = 0;
+}
+
+
+static void cquestsnd_exit(void)
+{
+ free(cquestsnd.sram);
+}
+
+
+/***************************************************************************
+ ROTATE INITIALIZATION AND SHUTDOWN
+***************************************************************************/
+
+static STATE_POSTLOAD( cquestrot_postload )
+{
+
+}
+
+static void cquestrot_state_register(int index, const char *type)
+{
+ state_save_register_item_array(type, index, cquestrot.ram);
+ state_save_register_item(type, index, cquestrot.q);
+ state_save_register_item(type, index, cquestrot.f);
+ state_save_register_item(type, index, cquestrot.y);
+ state_save_register_item(type, index, cquestrot.cflag);
+ state_save_register_item(type, index, cquestrot.vflag);
+
+ state_save_register_item(type, index, cquestrot.pc);
+ state_save_register_item(type, index, cquestrot.seqcnt);
+ state_save_register_item(type, index, cquestrot.dsrclatch);
+ state_save_register_item(type, index, cquestrot.rsrclatch);
+ state_save_register_item(type, index, cquestrot.dynaddr);
+ state_save_register_item(type, index, cquestrot.dyndata);
+ state_save_register_item(type, index, cquestrot.yrlatch);
+ state_save_register_item(type, index, cquestrot.ydlatch);
+ state_save_register_item(type, index, cquestrot.dinlatch);
+ state_save_register_item(type, index, cquestrot.divreg);
+ state_save_register_item(type, index, cquestrot.linedata);
+ state_save_register_item(type, index, cquestrot.lineaddr);
+ state_save_register_item(type, index, cquestrot.prev_dred);
+ state_save_register_item(type, index, cquestrot.prev_dwrt);
+ state_save_register_item(type, index, cquestrot.wc);
+
+ state_save_register_item_pointer(type, index, cquestrot.dram, 16384);
+ state_save_register_item_pointer(type, index, cquestrot.sram, 2048);
+
+ state_save_register_postload(Machine, cquestrot_postload, NULL);
+}
+
+static void cquestrot_init(int index, int clock, const void *_config, int (*irqcallback)(int))
+{
+ memset(&cquestrot, 0, sizeof(cquestrot));
+
+ cquestrot_state_register(index, "cquestrot");
+
+ /* Allocate RAM */
+ cquestrot.dram = malloc(16384 * sizeof(UINT16)); /* Shared with 68000 */
+ cquestrot.sram = malloc(2048 * sizeof(UINT16)); /* Private */
+}
+
+
+static void cquestrot_reset(void)
+{
+ cquestrot.pc = 0;
+ cquestrot.wc = 0;
+ cquestrot.prev_dred = 1;
+ cquestrot.prev_dwrt = 1;
+}
+
+
+static void cquestrot_exit(void)
+{
+ free(cquestrot.dram);
+ free(cquestrot.sram);
+}
+
+
+/***************************************************************************
+ LINE DRAWER INITIALIZATION AND SHUTDOWN
+***************************************************************************/
+#define FOREGROUND 0
+#define BACKGROUND 1
+#define ODD_FIELD 0
+#define EVEN_FIELD 1
+
+static STATE_POSTLOAD( cquestlin_postload )
+{
+
+}
+
+static void cquestlin_state_register(int index, const char *type)
+{
+ state_save_register_item_array(type, index, cquestlin.ram);
+ state_save_register_item(type, index, cquestlin.q);
+ state_save_register_item(type, index, cquestlin.f);
+ state_save_register_item(type, index, cquestlin.y);
+ state_save_register_item(type, index, cquestlin.cflag);
+ state_save_register_item(type, index, cquestlin.vflag);
+
+ state_save_register_item(type, index, cquestlin.pc[0]);
+ state_save_register_item(type, index, cquestlin.pc[1]);
+ state_save_register_item(type, index, cquestlin.seqcnt);
+ state_save_register_item(type, index, cquestlin.clatch);
+ state_save_register_item(type, index, cquestlin.zlatch);
+ state_save_register_item(type, index, cquestlin.xcnt);
+ state_save_register_item(type, index, cquestlin.ycnt);
+ state_save_register_item(type, index, cquestlin.sreg);
+ state_save_register_item(type, index, cquestlin.fadlatch);
+ state_save_register_item(type, index, cquestlin.badlatch);
+ state_save_register_item(type, index, cquestlin.sramdlatch);
+ state_save_register_item(type, index, cquestlin.fglatch);
+ state_save_register_item(type, index, cquestlin.bglatch);
+ state_save_register_item(type, index, cquestlin.gt0reg);
+ state_save_register_item(type, index, cquestlin.fdxreg);
+ state_save_register_item(type, index, cquestlin.field);
+ state_save_register_item(type, index, cquestlin.clkcnt);
+
+ state_save_register_item_pointer(type, index, cquestlin.sram, 4096);
+ state_save_register_item_pointer(type, index, cquestlin.ptr_ram, 1024);
+ state_save_register_item_pointer(type, index, cquestlin.e_stack, 32768);
+ state_save_register_item_pointer(type, index, cquestlin.o_stack, 32768);
+
+ state_save_register_postload(Machine, cquestlin_postload, NULL);
+}
+
+static void cquestlin_init(int index, int clock, const void *_config, int (*irqcallback)(int))
+{
+ memset(&cquestlin, 0, sizeof(cquestlin));
+
+ cquestlin_state_register(index, "cquestlin");
+
+ /* Allocate RAM */
+ cquestlin.sram = malloc(4096 * sizeof(UINT16)); /* Shared with rotate CPU */
+ cquestlin.ptr_ram = malloc(1024); /* Pointer RAM */
+ cquestlin.e_stack = malloc(32768 * sizeof(UINT32)); /* Stack DRAM: 32kx20 */
+ cquestlin.o_stack = malloc(32768 * sizeof(UINT32)); /* Stack DRAM: 32kx20 */
+}
+
+
+static void cquestlin_reset(void)
+{
+ cquestlin.clkcnt = 0;
+ cquestlin.pc[FOREGROUND] = 0;
+ cquestlin.pc[BACKGROUND] = 0x80;
+}
+
+
+static void cquestlin_exit(void)
+{
+ free(cquestlin.sram);
+ free(cquestlin.e_stack);
+ free(cquestlin.o_stack);
+ free(cquestlin.ptr_ram);
+}
+
+
+/***************************************************************************
+ SOUND CORE EXECUTION LOOP
+***************************************************************************/
+
+#define SND_PC (cquestsnd.pc)
+#define SND_DATA_IN (_ramen ? cquestsnd.sound_data[cquestsnd.platch] : cquestsnd.dinlatch)
+
+enum
+{
+ PLTCH = 0,
+ DAC = 1,
+ ADLATCH = 2,
+} snd_latch_type;
+
+static int do_sndjmp(int jmp)
+{
+ switch (jmp)
+ {
+ /* JUMP */ case 0: return 1;
+ /* MSB */ case 2: return cquestsnd.f & 0x8000 ? 0 : 1;
+ /* !MSB */ case 3: return cquestsnd.f & 0x8000 ? 1 : 0;
+ /* ZERO */ case 5: return cquestsnd.f == 0 ? 0 : 1;
+ /* OVR */ case 6: return cquestsnd.vflag ? 0 : 1;
+ /* LOOP */ case 7: return cquestsnd.adrcntr & 0x80 ? 0: 1;
+ }
+
+ return 0;
+}
+
+static int cquestsnd_execute(int cycles)
+{
+ int calldebugger = ((Machine->debug_flags & DEBUG_FLAG_ENABLED) != 0);
+
+ cquestsnd_icount = cycles;
+
+ /* Core execution loop */
+ do
+ {
+ /* Decode the instruction */
+ UINT64 inst = cpu_readop64(SND_PC << 3);
+ UINT32 inslow = inst & 0xffffffff;
+ UINT32 inshig = inst >> 32;
+
+ int t = (inshig >> 24) & 0xff;
+ int b = (inshig >> 20) & 0xf;
+ int a = (inshig >> 16) & 0xf;
+ int ci = (inshig >> 15) & 1;
+ int i5_3 = (inshig >> 12) & 7;
+ int _ramen = (inshig >> 11) & 1;
+ int i2_0 = (inshig >> 8) & 7;
+ int rtnltch = (inshig >> 7) & 1;
+ int jmp = (inshig >> 4) & 7;
+ int inca = (inshig >> 3) & 1;
+ int i8_6 = (inshig >> 0) & 7;
+ int _ipram = (inslow >> 31) & 1;
+ int _ipwrt = (inslow >> 30) & 1;
+ int latch = (inslow >> 28) & 3;
+ int rtn = (inslow >> 27) & 1;
+ int _rin = (inslow >> 26) & 1;
+
+ if (calldebugger)
+ debugger_instruction_hook(Machine, cquestsnd.pc);
+
+ /* Don't think this matters, but just in case */
+ if (rtn)
+ t = cquestsnd.rtnlatch;
+
+ /* Handle the AM2901 ALU instruction */
+ {
+ UINT16 r = 0;
+ UINT16 s = 0;
+
+ UINT32 res = 0;
+ UINT32 cflag = 0;
+ UINT32 vflag = 0;
+
+ /* Determine the ALU sources */
+ switch (i2_0)
+ {
+ case AQ: r = cquestsnd.ram[a]; s = cquestsnd.q; break;
+ case AB: r = cquestsnd.ram[a]; s = cquestsnd.ram[b]; break;
+ case ZQ: r = 0; s = cquestsnd.q; break;
+ case ZB: r = 0; s = cquestsnd.ram[b]; break;
+ case ZA: r = 0; s = cquestsnd.ram[a]; break;
+ case DA: r = SND_DATA_IN; s = cquestsnd.ram[a]; break;
+ case DQ: r = SND_DATA_IN; s = cquestsnd.q; break;
+ case DZ: r = SND_DATA_IN; s = 0; break;
+ }
+
+ /* Perform the ALU operation */
+ switch (i5_3)
+ {
+ case ADD:
+ res = r + s + ci;
+ cflag = (res >> 16) & 1;
+ vflag = (((r & 0x7fff) + (s & 0x7fff) + ci) >> 15) ^ cflag;
+ break;
+ case SUBR:
+ res = ~r + s + ci;
+ cflag = (res >> 16) & 1;
+ vflag = (((s & 0x7fff) + (~r & 0x7fff) + ci) >> 15) ^ cflag;
+ break;
+ case SUBS:
+ res = r + ~s + ci;
+ cflag = (res >> 16) & 1;
+ vflag = (((r & 0x7fff) + (~s & 0x7fff) + ci) >> 15) ^ cflag;
+ break;
+ case OR:
+ res = r | s;
+ break;
+ case AND:
+ res = r & s;
+ break;
+ case NOTRS:
+ res = ~r & s;
+ break;
+ case EXOR:
+ res = r ^ s;
+ break;
+ case EXNOR:
+ res = ~(r ^ s);
+ break;
+ }
+
+ cquestsnd.f = res;
+ cquestsnd.cflag = cflag;
+ cquestsnd.vflag = vflag;
+
+ switch (i8_6)
+ {
+ case QREG:
+ cquestsnd.q = cquestsnd.f;
+ cquestsnd.y = cquestsnd.f;
+ break;
+ case NOP:
+ cquestsnd.y = cquestsnd.f;
+ break;
+ case RAMA:
+ cquestsnd.y = cquestsnd.ram[a];
+ cquestsnd.ram[b] = cquestsnd.f;
+ break;
+ case RAMF:
+ cquestsnd.ram[b] = cquestsnd.f;
+ cquestsnd.y = cquestsnd.f;
+ break;
+ case RAMQD:
+ {
+ UINT16 qin;
+
+ cquestsnd.ram[b] = (_rin ? 0 : 0x8000) | (cquestsnd.f >> 1);
+ cquestsnd.q >>= 1;
+ cquestsnd.y = cquestsnd.f;
+
+ /* When right shifting Q, we need to OR in a value */
+ qin = (((cquestsnd.y >> 15) ^ (cquestsnd.y >> 1)) & 1) ? 0 : 0x8000;
+
+ cquestsnd.q |= qin;
+ break;
+ }
+ case RAMD:
+ cquestsnd.ram[b] = (_rin ? 0 : 0x8000) | (cquestsnd.f >> 1);
+ cquestsnd.y = cquestsnd.f;
+ break;
+ case RAMQU:
+ cquestsnd.ram[b] = (cquestsnd.f << 1) | (_rin ? 0 : 0x0001);
+ cquestsnd.q <<= 1;
+ cquestsnd.y = cquestsnd.f;
+ break;
+ case RAMU:
+ cquestsnd.ram[b] = (cquestsnd.f << 1) | (_rin ? 0 : 0x0001);
+ cquestsnd.y = cquestsnd.f;
+ break;
+ }
+ }
+
+ /* Now handle any SRAM accesses from the previous cycle */
+ if (!cquestsnd.prev_ipram)
+ {
+ UINT16 addr = cquestsnd.adrlatch | (cquestsnd.adrcntr & 0x7f);
+
+ if (!cquestsnd.prev_ipwrt)
+ cquestsnd.sram[addr] = cquestsnd.ramwlatch;
+ else
+ cquestsnd.dinlatch = cquestsnd.sram[addr];
+ }
+
+ /* Handle latches */
+ if (latch == PLTCH)
+ {
+ cquestsnd.platch = ((t & 3) << 9) | ((cquestsnd.y >> 6) & 0x1ff);
+ }
+ else if (latch == DAC)
+ {
+ cquestsnd.dac_w((cquestsnd.y & 0xfff0) | ((cquestsnd.adrcntr >> 3) & 0xf));
+ }
+ else if (latch == ADLATCH)
+ {
+ /* Load the SRAM address counter - this value is instantly loaded */
+ cquestsnd.adrcntr = cquestsnd.y & 0x7f;
+
+ /* Also load the SRAM address latch */
+ cquestsnd.adrlatch = cquestsnd.y & 0x780;
+ }
+
+ /* Check for jump/return */
+ if ( do_sndjmp(jmp) )
+ cquestsnd.pc = rtn ? cquestsnd.rtnlatch : t;
+ else
+ cquestsnd.pc++;
+
+ /* Load the return latch? (Obviously a load and a ret in the same cycle are invalid) */
+ if (rtnltch)
+ cquestsnd.rtnlatch = t;
+
+ /* Only increment the sound counter if not loading */
+ if (inca && latch != ADLATCH)
+ cquestsnd.adrcntr++;
+
+ /* Latch data for a RAM write (do actual write on the next cycle) */
+ if (!_ipwrt)
+ cquestsnd.ramwlatch = cquestsnd.y;
+
+ /* Save level sensitive bits */
+ cquestsnd.prev_ipram = _ipram;
+ cquestsnd.prev_ipwrt = _ipwrt;
+
+ cquestsnd_icount--;
+ } while (cquestsnd_icount > 0);
+
+ return cycles - cquestsnd_icount;
+}
+
+
+/***************************************************************************
+ SOUND DISASSEMBLY HOOK
+***************************************************************************/
+
+static offs_t cquestsnd_dasm(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram)
+{
+ static const char* jmps[] =
+ {
+ "JUMP ",
+ " ",
+ "JMSB ",
+ "JNMSB",
+ " ",
+ "JZERO",
+ "JOVR ",
+ "JLOOP",
+ };
+
+
+ static const char* latches[] =
+ {
+ "PLTCH ",
+ "DAC ",
+ "ADLATCH",
+ " ",
+ };
+
+ UINT64 inst = BIG_ENDIANIZE_INT64(*(UINT64 *)oprom);
+ UINT32 inslow = inst & 0xffffffff;
+ UINT32 inshig = inst >> 32;
+
+ int t = (inshig >> 24) & 0xff;
+ int b = (inshig >> 20) & 0xf;
+ int a = (inshig >> 16) & 0xf;
+ int ci = (inshig >> 15) & 1;
+ int i5_3 = (inshig >> 12) & 7;
+ int _ramen = (inshig >> 11) & 1;
+ int i2_0 = (inshig >> 8) & 7;
+ int rtnltch = (inshig >> 7) & 1;
+ int jmp = (inshig >> 4) & 7;
+ int inca = (inshig >> 3) & 1;
+ int i8_6 = (inshig >> 0) & 7;
+ int _ipram = (inslow >> 31) & 1;
+ int _ipwrt = (inslow >> 30) & 1;
+ int latch = (inslow >> 28) & 3;
+ int rtn = (inslow >> 27) & 1;
+ int _rin = (inslow >> 26) & 1;
+
+
+ sprintf(buffer, "%s %s %s %x,%x,%c %.2x %s %s %.2x %s %s %s %c %c %c\n",
+ ins[i5_3],
+ src[i2_0],
+ dst[i8_6],
+ a,
+ b,
+ ci ? 'C' : ' ',
+ _rin,
+ jmps[jmp],
+ rtn ? "RET" : " ",
+ t,
+ latches[latch],
+ rtnltch ? "RTLATCH" : " ",
+ _ramen ? "PROM" : "RAM ",
+ _ipram ? ' ' : 'R',
+ _ipwrt ? ' ' : 'W',
+ inca ? 'I' : ' ');
+
+ return 1 | DASMFLAG_SUPPORTED;
+}
+
+
+/***************************************************************************
+ ROTATE CORE EXECUTION LOOP
+***************************************************************************/
+
+#define ROT_PC (cquestrot.pc & 0x1ff)
+
+enum
+{
+ SPF_UNUSED0 = 0,
+ SPF_UNUSED1 = 1,
+ SPF_OP = 2,
+ SPF_RET = 3,
+ SPF_SQLTCH = 4,
+ SPF_SWRT = 5,
+ SPF_DIV = 6,
+ SPF_MULT = 7,
+ SPF_DRED = 8,
+ SPF_DWRT = 9,
+} rot_spf;
+
+enum
+{
+ YOUT_UNUSED0 = 0,
+ YOUT_UNUSED1 = 1,
+ YOUT_Y2LDA = 2,
+ YOUT_Y2LDD = 3,
+ YOUT_Y2DAD = 4,
+ YOUT_Y2DYN = 5,
+ YOUT_Y2R = 6,
+ YOUT_Y2D = 7,
+} rot_yout;
+
+/* Sync is asserted for the duration of every fourth cycle */
+/* The Dynamic RAM latch clocks in a value at the end of this cycle */
+/* So CPU waits for sync before reading from DRAM */
+
+INLINE int do_rotjmp(int jmp)
+{
+ int ret = 0;
+
+ switch (jmp & 7)
+ {
+ /* */ case 0: ret = 0; break;
+ /* SEQ */ case 1: ret = (cquestrot.seqcnt == 0xf); break;
+ /* CAROUT */ case 2: ret = cquestrot.cflag; break;
+ /* SYNC */ case 3: ret = !(cquestrot.clkcnt & 0x3); break;
+ /* LDWAIT */ case 4: ret = 0; break;
+ /* MSB */ case 5: ret = BIT(cquestrot.f, 15); break;
+ /* >=1 */ case 6: ret = (!_BIT(cquestrot.f, 15) && !(cquestrot.f == 0)); break;
+ /* ZERO */ case 7: ret = (cquestrot.f == 0); break;
+ }
+
+ return !(!ret ^ BIT(jmp, 3));
+}
+
+
+#define ROT_SRAM_ADDRESS ((cquestrot.dsrclatch & 2) ? cquestrot.yrlatch : (cquestrot.rsrclatch | 0x700))
+
+
+static int cquestrot_execute(int cycles)
+{
+ int calldebugger = ((Machine->debug_flags & DEBUG_FLAG_ENABLED) != 0);
+
+ cquestrot_icount = cycles;
+
+ /* Core execution loop */
+ do
+ {
+ /* Decode the instruction */
+ UINT64 inst = cpu_readop64(ROT_PC << 3);
+
+ UINT32 inslow = inst & 0xffffffff;
+ UINT32 inshig = inst >> 32;
+
+ int t = (inshig >> 20) & 0xfff;
+ int jmp = (inshig >> 16) & 0xf;
+ int spf = (inshig >> 12) & 0xf;
+ int rsrc = (inshig >> 11) & 0x1;
+ int yout = (inshig >> 8) & 0x7;
+ int sel = (inshig >> 6) & 0x3;
+ int dsrc = (inshig >> 4) & 0x3;
+ int b = (inshig >> 0) & 0xf;
+ int a = (inslow >> 28) & 0xf;
+ int i8_6 = (inslow >> 24) & 0x7;
+ int ci = (inslow >> 23) & 0x1;
+ int i5_3 = (inslow >> 20) & 0x7;
+ int _sex = (inslow >> 19) & 0x1;
+ int i2_0 = (inslow >> 16) & 0x7;
+
+ int dsrclatch;
+ UINT16 data_in = 0xffff;
+
+ if (calldebugger)
+ debugger_instruction_hook(Machine, ROT_PC);
+
+ /* Handle DRAM accesses - I ought to check this... */
+ if (!(cquestrot.clkcnt & 3))
+ {
+ if (cquestrot.wc)
+ {
+ cquestrot.wc = 0;
+ cquestrot.dram[cquestrot.dynaddr & 0x3fff] = cquestrot.dyndata;
+ }
+ if (cquestrot.rc)
+ {
+ cquestrot.rc = 0;
+ cquestrot.dinlatch = cquestrot.dram[cquestrot.dynaddr & 0x3fff];
+ }
+ }
+
+ /* Flag pending DRAM accesses */
+ if (!cquestrot.prev_dwrt)
+ cquestrot.wc = 1;
+ else if (!cquestrot.prev_dred)
+ cquestrot.rc = 1;
+
+ /* What's on the D-Bus? */
+ if (~cquestrot.dsrclatch & 0x10)
+ data_in = cquestrot.dinlatch;
+ else if (~cquestrot.dsrclatch & 0x20)
+ data_in = cquestrot.sram[ROT_SRAM_ADDRESS];
+ else if (~cquestrot.dsrclatch & 0x40)
+ data_in = cquestrot.ydlatch;
+ else if (~cquestrot.dsrclatch & 0x80)
+ data_in = t & 0xfff;
+
+ /* What's on the T-Bus? */
+ if ((spf == SPF_RET) && (cquestrot.dsrclatch & 0x80))
+ t = data_in;
+ else if (spf == SPF_OP)
+ t = (t & ~0xf) | (data_in >> 12);
+
+
+ if (~cquestrot.dsrclatch & 1)
+ cquestrot.sram[ROT_SRAM_ADDRESS] = data_in;
+
+
+ /* Sign extend ALU input? */
+ if (!_sex)
+ data_in = (data_in & ~0xf000) | ((data_in & 0x800) ? 0xf000 : 0);
+
+ /* No do the ALU operation */
+ {
+ UINT16 r = 0;
+ UINT16 s = 0;
+
+ UINT32 res = 0;
+ UINT32 cflag = 0;
+ UINT32 vflag = 0;
+
+ /* First, determine correct I1 bit */
+ if ((spf == SPF_MULT) && !_BIT(cquestrot.q, 0))
+ i2_0 |= 2;
+
+ /* Determine the ALU sources */
+ switch (i2_0)
+ {
+ case 0: r = cquestrot.ram[a]; s = cquestrot.q; break;
+ case 1: r = cquestrot.ram[a]; s = cquestrot.ram[b]; break;
+ case 2: r = 0; s = cquestrot.q; break;
+ case 3: r = 0; s = cquestrot.ram[b]; break;
+ case 4: r = 0; s = cquestrot.ram[a]; break;
+ case 5: r = data_in; s = cquestrot.ram[a]; break;
+ case 6: r = data_in; s = cquestrot.q; break;
+ case 7: r = data_in; s = 0; break;
+ }
+
+ /* Next, determine the I3 and carry bits */
+ if ((spf == SPF_DIV) && cquestrot.divreg)
+ {
+ i5_3 |= 1;
+ ci = 1;
+ }
+
+ /* Perform the ALU operation */
+ switch (i5_3)
+ {
+ case ADD:
+ res = r + s + ci;
+ cflag = (res >> 16) & 1;
+ vflag = (((r & 0x7fff) + (s & 0x7fff) + ci) >> 15) ^ cflag;
+ break;
+ case SUBR:
+ res = ~r + s + ci;
+ cflag = (res >> 16) & 1;
+ vflag = (((s & 0x7fff) + (~r & 0x7fff) + ci) >> 15) ^ cflag;
+ break;
+ case SUBS:
+ res = r + ~s + ci;
+ cflag = (res >> 16) & 1;
+ vflag = (((r & 0x7fff) + (~s & 0x7fff) + ci) >> 15) ^ cflag;
+ break;
+ case OR:
+ res = r | s;
+ break;
+ case AND:
+ res = r & s;
+ break;
+ case NOTRS:
+ res = ~r & s;
+ break;
+ case EXOR:
+ res = r ^ s;
+ break;
+ case EXNOR:
+ res = ~(r ^ s);
+ break;
+ }
+
+ cquestrot.f = res;
+ cquestrot.cflag = cflag;
+ cquestrot.vflag = vflag;
+
+ switch (i8_6)
+ {
+ case QREG:
+ cquestrot.q = cquestrot.f;
+ cquestrot.y = cquestrot.f;
+ break;
+ case NOP:
+ cquestrot.y = cquestrot.f;
+ break;
+ case RAMA:
+ cquestrot.y = cquestrot.ram[a];
+ cquestrot.ram[b] = cquestrot.f;
+ break;
+ case RAMF:
+ cquestrot.ram[b] = cquestrot.f;
+ cquestrot.y = cquestrot.f;
+ break;
+ case RAMQD:
+ {
+ UINT16 q0 = cquestrot.q & 1;
+ UINT16 r0 = cquestrot.f & 1;
+ UINT16 q15 = 0;
+ UINT16 r15 = 0;
+
+ /* Determine Q15 and RAM15 */
+ switch (sel)
+ {
+ case 0: q15 = r15 = 0;
+ break;
+ case 1: q15 = r15 = 0x8000;
+ break;
+ case 2: q15 = q0 << 15;
+ r15 = r0 << 15;
+ break;
+ case 3: q15 = r0 << 15;
+ r15 = (cquestrot.vflag ^ BIT(cquestrot.f, 15)) << 15;
+ break;
+ }
+
+ cquestrot.ram[b] = r15 | (cquestrot.f >> 1);
+ cquestrot.q = q15 | (cquestrot.q >> 1);
+ cquestrot.y = cquestrot.f;
+ break;
+ }
+ case RAMD:
+ {
+ UINT16 r0 = cquestrot.f & 1;
+ UINT16 r15 = 0;
+
+ switch (sel)
+ {
+ case 0: r15 = 0; break;
+ case 1: r15 = 0x8000; break;
+ case 2: r15 = r0 << 15; break;
+ case 3:
+ r15 = (cquestrot.vflag ^ BIT(cquestrot.f, 15)) << 15;
+ break;
+ }
+
+ cquestrot.ram[b] = r15 | (cquestrot.f >> 1);
+ cquestrot.y = cquestrot.f;
+ break;
+ }
+ case RAMQU:
+ {
+ UINT16 q15 = BIT(cquestrot.q, 15);
+ UINT16 r15 = BIT(cquestrot.f, 15);
+ UINT16 q0 = 0;
+ UINT16 r0 = 0;
+
+ switch (sel)
+ {
+ case 0: q0 = 0; r0 = 0; break;
+ case 1: q0 = 1; r0 = 1; break;
+ case 2: q0 = q15; r0 = r15; break;
+ case 3:
+ {
+ q0 = (spf == SPF_DIV) && !BIT(cquestrot.f, 15);
+ r0 = q15;
+ break;
+ }
+ }
+
+ cquestrot.ram[b] = (cquestrot.f << 1) | r0;
+ cquestrot.q = (cquestrot.q << 1) | q0;
+ cquestrot.y = cquestrot.f;
+ break;
+ }
+ case RAMU:
+ {
+
+ UINT16 q15 = BIT(cquestrot.q, 15);
+ UINT16 r15 = BIT(cquestrot.f, 15);
+ UINT16 r0 = 0;
+
+ switch (sel)
+ {
+ case 0: r0 = 0; break;
+ case 1: r0 = 1; break;
+ case 2: r0 = r15; break;
+ case 3: r0 = q15; break;
+ }
+
+ cquestrot.ram[b] = (cquestrot.f << 1) | r0;
+ cquestrot.y = cquestrot.f;
+ break;
+ }
+ }
+ }
+
+ /* Check for jump */
+ if ( do_rotjmp(jmp) )
+ cquestrot.pc = t;
+ else
+ cquestrot.pc = (cquestrot.pc + 1) & 0xfff;
+
+ /* Rising edge; update the sequence counter */
+ if (spf == SPF_SQLTCH)
+ cquestrot.seqcnt = t & 0xf;
+ else if ( (spf == SPF_MULT) || (spf == SPF_DIV) )
+ cquestrot.seqcnt = (cquestrot.seqcnt + 1) & 0xf;
+
+ /* Rising edge; write data source reg */
+ dsrclatch =
+ (~(0x10 << dsrc) & 0xf0)
+ | (rsrc ? 0x04 : 0x02)
+ | !(spf == SPF_SWRT);
+
+ /* R-latch is written on rising edge of dsrclatch bit 2 */
+ if (!_BIT(cquestrot.dsrclatch, 2) && _BIT(dsrclatch, 2))
+ cquestrot.rsrclatch = t & 0xff;
+
+ cquestrot.dsrclatch = dsrclatch;
+
+ /* Handle latching on rising edge */
+ switch (yout)
+ {
+ case YOUT_Y2LDA:
+ {
+ cquestrot.lineaddr = cquestrot.y & 0xfff;
+ break;
+ }
+ case YOUT_Y2LDD:
+ {
+ cquestrot.linedata = ((t & 0xf) << 12) | (cquestrot.y & 0xfff);
+ cquestlin.sram[cquestrot.lineaddr] = cquestrot.linedata;
+ break;
+ }
+ case YOUT_Y2DAD: cquestrot.dynaddr = cquestrot.y & 0x3fff; break;
+ case YOUT_Y2DYN: cquestrot.dyndata = cquestrot.y & 0xffff; break;
+ case YOUT_Y2R: cquestrot.yrlatch = cquestrot.y & 0x7ff; break;
+ case YOUT_Y2D: cquestrot.ydlatch = cquestrot.y; break;
+ }
+
+ /* Clock in the divide register */
+ cquestrot.divreg = (spf == SPF_DIV) && !_BIT(cquestrot.f, 15);
+
+ /* DRAM accessing */
+ cquestrot.prev_dred = !(spf == SPF_DRED);
+ cquestrot.prev_dwrt = !(spf == SPF_DWRT);
+
+ cquestrot.clkcnt++;
+ cquestrot_icount--;
+ } while (cquestrot_icount > 0);
+
+ return cycles - cquestrot_icount;
+}
+
+
+/***************************************************************************
+ ROTATE DISASSEMBLY HOOK
+***************************************************************************/
+
+static offs_t cquestrot_dasm(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram)
+{
+ static const char* jmps[] =
+ {
+ " ",
+ "JSEQ ",
+ "JC ",
+ "JSYNC ",
+ "JLDWAIT",
+ "JMSB ",
+ "JGEONE ",
+ "JZERO ",
+
+ "JUMP ",
+ "JNSEQ ",
+ "JNC ",
+ "JNSYNC ",
+ "JNLDWAI",
+ "JNMSB ",
+ "JLTONE ",
+ "JNZERO ",
+ };
+
+ static const char* youts[] =
+ {
+ " ",
+ " ",
+ "Y2LDA",
+ "Y2LDD",
+ "Y2DAD",
+ "Y2DIN",
+ "Y2R ",
+ "Y2D ",
+ };
+
+ static const char* spfs[] =
+ {
+ " ",
+ " ",
+ "OP ",
+ "RET ",
+ "SQLTCH",
+ "SWRT ",
+ "DIV ",
+ "MULT ",
+
+ "DRED ",
+ "DWRT ",
+ "??? ",
+ "??? ",
+ "??? ",
+ "??? ",
+ "??? ",
+ "??? "
+ };
+
+ UINT64 inst = BIG_ENDIANIZE_INT64(*(UINT64 *)oprom);
+ UINT32 inslow = inst & 0xffffffff;
+ UINT32 inshig = inst >> 32;
+
+ int t = (inshig >> 20) & 0xfff;
+ int jmp = (inshig >> 16) & 0xf;
+ int spf = (inshig >> 12) & 0xf;
+// int rsrc = (inshig >> 11) & 0x1;
+ int yout = (inshig >> 8) & 0x7;
+ int sel = (inshig >> 6) & 0x3;
+// int dsrc = (inshig >> 4) & 0x3;
+ int b = (inshig >> 0) & 0xf;
+ int a = (inslow >> 28) & 0xf;
+ int i8_6 = (inslow >> 24) & 0x7;
+ int ci = (inslow >> 23) & 0x1;
+ int i5_3 = (inslow >> 20) & 0x7;
+// int _sex = (inslow >> 19) & 0x1;
+ int i2_0 = (inslow >> 16) & 0x7;
+
+ sprintf(buffer, "%s %s,%s %x,%x,%c %d %s %s %s %.2x\n",
+ ins[i5_3],
+ src[i2_0],
+ dst[i8_6],
+ a,
+ b,
+ ci ? 'C' : ' ',
+ sel,
+ jmps[jmp],
+ youts[yout],
+ spfs[spf],
+ t);
+
+ return 1 | DASMFLAG_SUPPORTED;
+}
+
+/***************************************************************************
+ LINE DRAWER CORE EXECUTION LOOP
+***************************************************************************/
+
+#define VISIBLE_FIELD !cquestlin.field
+
+enum
+{
+ LSPF_UNUSUED = 0,
+ LSPF_FSTOP = 1,
+ LSPF_SREG = 2,
+ LSPF_FSTRT = 3,
+ LSPF_PWRT = 4,
+ LSPF_MULT = 5,
+ LSPF_LSTOP = 6,
+ LSPF_BRES = 7,
+} line_spf;
+
+enum
+{
+ LLATCH_UNUSED = 0,
+ LLATCH_SEQLATCH = 1,
+ LLATCH_XLATCH = 2,
+ LLATCH_YLATCH = 3,
+ LLATCH_BADLATCH = 4,
+ LLATCH_FADLATCH = 5,
+ LLATCH_CLATCH = 6,
+ LLATCH_ZLATCH = 7,
+} line_latch;
+
+enum
+{
+ SREG_E0 = 0,
+ SREG_DX_DY = 1,
+ SREG_DY = 2,
+ SREG_DX = 3,
+ SREG_LE0 = 4,
+ SREG_LDX_DY = 5,
+ SREG_LDY = 6,
+ SREG_LDX = 7,
+} sreg_bits;
+
+INLINE int do_linjmp(int jmp)
+{
+ int ret = 0;
+
+ switch (jmp & 7)
+ {
+ /* */ case 0: ret = 0; break;
+ /* MSB */ case 1: ret = BIT(cquestlin.f, 11); break;
+ /* SEQ */ case 2: ret = (cquestlin.seqcnt == 0xfff); break;
+ /* >0 */ case 3: ret = !(cquestlin.f == 0) && !_BIT(cquestlin.f, 11); break;
+ /* CAROUT */ case 4: ret = (cquestlin.cflag); break;
+ /* ZERO */ case 5: ret = (cquestlin.f == 0); break;
+ }
+
+ return !(!ret ^ BIT(jmp, 3));
+}
+
+
+
+void cubeqcpu_swap_line_banks(void)
+{
+ cquestlin.field = cquestlin.field ^ 1;
+}
+
+
+void clear_stack(void)
+{
+ memset(&cquestlin.ptr_ram[cquestlin.field * 256], 0, 256);
+}
+
+UINT8 get_ptr_ram_val(int i)
+{
+ return cquestlin.ptr_ram[(VISIBLE_FIELD * 256) + i];
+}
+
+UINT32* get_stack_ram(void)
+{
+ if (VISIBLE_FIELD == ODD_FIELD)
+ return cquestlin.o_stack;
+ else
+ return cquestlin.e_stack;
+}
+
+
+static int cquestlin_execute(int cycles)
+{
+#define LINE_PC ((cquestlin.pc[prog] & 0x7f) | ((prog == BACKGROUND) ? 0x80 : 0))
+
+ int calldebugger = ((Machine->debug_flags & DEBUG_FLAG_ENABLED) != 0);
+ UINT32 *stack_ram;
+ UINT8 *ptr_ram;
+
+ /* Check the field and set the stack/pointer RAM pointers appropriately */
+ if (cquestlin.field == ODD_FIELD)
+ {
+ stack_ram = cquestlin.o_stack;
+ ptr_ram = &cquestlin.ptr_ram[0];
+ }
+ else
+ {
+ stack_ram = cquestlin.e_stack;
+ ptr_ram = &cquestlin.ptr_ram[0x100];
+ }
+
+ cquestlin_icount = cycles;
+
+ /* Core execution loop */
+ do
+ {
+ /* Are we executing the foreground or backgroud program? */
+ int prog = (cquestlin.clkcnt & 3) ? BACKGROUND : FOREGROUND;
+
+ UINT64 inst = cpu_readop64(LINE_PC << 3);
+
+ UINT32 inslow = inst & 0xffffffff;
+ UINT32 inshig = inst >> 32;
+
+ int t = (inshig >> 24) & 0xff;
+ int jmp = (inshig >> 20) & 0xf;
+ int latch = (inshig >> 16) & 0x7;
+ int op = (inshig >> 15) & 0x1;
+ int spf = (inshig >> 12) & 0x7;
+ int b = (inshig >> 8) & 0xf;
+ int a = (inshig >> 4) & 0xf;
+ int i8_6 = (inshig >> 0) & 0x7;
+ int ci = (inslow >> 31) & 0x1;
+ int i5_3 = (inslow >> 28) & 0x7;
+ int _pbcs = (inslow >> 27) & 0x1;
+ int i2_0 = (inslow >> 24) & 0x7;
+
+ UINT16 data_in = 0;
+
+ if (calldebugger)
+ debugger_instruction_hook(Machine, cquestlin.pc[prog]);
+
+ /* Handle accesses to and from shared SRAM */
+ if (prog == FOREGROUND)
+ {
+ if (!_BIT(cquestlin.fglatch, 5))
+ data_in = cquestlin.sram[cquestlin.fadlatch];
+ else
+ data_in = cquestrot.linedata;
+ }
+ else
+ {
+ if (!_BIT(cquestlin.bglatch, 4))
+ cquestlin.sram[cquestlin.badlatch] = cquestlin.sramdlatch;
+ else if (_BIT(cquestlin.bglatch, 2))
+ data_in = cquestlin.sram[cquestlin.badlatch];
+ else
+ data_in = cquestrot.linedata;
+ }
+
+ /* Handle a write to stack RAM (/DOWRT) */
+ if ((cquestlin.clkcnt & 3) == 1)
+ {
+ if (_BIT(cquestlin.fglatch, 4) && (cquestlin.ycnt < 256))
+ {
+ /* 20-bit words */
+ UINT32 data;
+ UINT16 h = cquestlin.xcnt;
+ UINT8 v = cquestlin.ycnt & 0xff;
+
+ /* Clamp H between 0 and 319 */
+ if (h >= 320)
+ h = (h & 0x800) ? 0 : 319;
+
+ /* Stack word type depends on STOP/#START bit */
+ if ( _BIT(cquestlin.fglatch, 3) )
+ data = (0 << 19) | (h << 8) | cquestlin.zlatch;
+ else
+ data = (1 << 19) | ((cquestlin.clatch & 0x100) << 9) | (h << 8) | (cquestlin.clatch & 0xff);
+
+ stack_ram[(v << 7) | (ptr_ram[v] & 0x7f)] = data;
+
+ /* Also increment the pointer RAM entry. Note that it cannot exceed 128 */
+ ptr_ram[v] = (ptr_ram[v] + 1) & 0x7f;
+ }
+ }
+
+ /* Override T3-0? */
+ if (op)
+ t = (t & ~0xf) | (data_in >> 12);
+
+ /* Determine the correct I1 bit */
+ if ((spf == LSPF_MULT) && !_BIT(cquestlin.q, 0))
+ i2_0 |= 2;
+
+ /* Determine A0 (BRESA0) */
+ if ((prog == FOREGROUND) && !_BIT(cquestlin.fglatch, 2))
+ a |= cquestlin.gt0reg;
+
+ /* Now do the ALU operation */
+ {
+ UINT16 r = 0;
+ UINT16 s = 0;
+
+ UINT16 res = 0;
+ UINT32 cflag = 0;
+ UINT32 vflag = 0;
+
+ /* Determine the ALU sources */
+ switch (i2_0)
+ {
+ case 0: r = cquestlin.ram[a]; s = cquestlin.q; break;
+ case 1: r = cquestlin.ram[a]; s = cquestlin.ram[b]; break;
+ case 2: r = 0; s = cquestlin.q; break;
+ case 3: r = 0; s = cquestlin.ram[b]; break;
+ case 4: r = 0; s = cquestlin.ram[a]; break;
+ case 5: r = data_in; s = cquestlin.ram[a]; break;
+ case 6: r = data_in; s = cquestlin.q; break;
+ case 7: r = data_in; s = 0; break;
+ }
+
+ /* 12-bits */
+ r &= 0xfff;
+ s &= 0xfff;
+
+ /* Perform the 12-bit ALU operation */
+ switch (i5_3)
+ {
+ case ADD:
+ res = r + s + ci;
+ cflag = (res >> 12) & 1;
+ vflag = (((r & 0x7ff) + (s & 0x7ff) + ci) >> 11) ^ cflag;
+ break;
+ case SUBR:
+ res = ~r + s + ci;
+ cflag = (res >> 12) & 1;
+ vflag = (((s & 0x7ff) + (~r & 0x7ff) + ci) >> 11) ^ cflag;
+ break;
+ case SUBS:
+ res = r + ~s + ci;
+ cflag = (res >> 12) & 1;
+ vflag = (((r & 0x7ff) + (~s & 0x7ff) + ci) >> 11) ^ cflag;
+ break;
+ case OR:
+ res = r | s;
+ break;
+ case AND:
+ res = r & s;
+ break;
+ case NOTRS:
+ res = ~r & s;
+ break;
+ case EXOR:
+ res = r ^ s;
+ break;
+ case EXNOR:
+ res = ~(r ^ s);
+ break;
+ }
+
+ cquestlin.f = res & 0xfff;
+ cquestlin.cflag = cflag;
+ cquestlin.vflag = vflag;
+
+ switch (i8_6)
+ {
+ case QREG:
+ cquestlin.q = cquestlin.f;
+ cquestlin.y = cquestlin.f;
+ break;
+ case NOP:
+ cquestlin.y = cquestlin.f;
+ break;
+ case RAMA:
+ cquestlin.y = cquestlin.ram[a];
+ cquestlin.ram[b] = cquestlin.f;
+ break;
+ case RAMF:
+ cquestlin.ram[b] = cquestlin.f;
+ cquestlin.y = cquestlin.f;
+ break;
+ case RAMQD:
+ {
+ UINT16 r11 = (BIT(cquestlin.f, 11) ^ cquestlin.vflag) ? 0x800 : 0;
+ UINT16 q11 = (prog == BACKGROUND) ? 0x800 : 0;
+
+ cquestlin.ram[b] = r11 | (cquestlin.f >> 1);
+ cquestlin.q = q11 | (cquestlin.q >> 1);
+ cquestlin.y = cquestlin.f;
+ break;
+ }
+ case RAMD:
+ {
+ UINT16 r11 = (BIT(cquestlin.f, 11) ^ cquestlin.vflag) ? 0x800 : 0;
+
+ cquestlin.ram[b] = r11 | (cquestlin.f >> 1);
+ cquestlin.y = cquestlin.f;
+ break;
+ }
+ case RAMQU:
+ {
+ /* Determine shift inputs */
+ UINT16 r0 = (prog == BACKGROUND);
+
+ /* This should never happen - Q0 will be invalid */
+ cquestlin.ram[b] = (cquestlin.f << 1) | r0;
+ cquestlin.q = (cquestlin.q << 1) | 0;
+ cquestlin.y = cquestlin.f;
+ break;
+ }
+ case RAMU:
+ {
+ UINT16 r0 = (prog == BACKGROUND);
+
+ cquestlin.ram[b] = (cquestlin.f << 1) | r0;
+ cquestlin.y = cquestlin.f;
+ break;
+ }
+ }
+ }
+
+ /* Adjust program counter */
+ if ( do_linjmp(jmp) )
+ cquestlin.pc[prog] = t & 0x7f;
+ else
+ cquestlin.pc[prog] = (cquestlin.pc[prog] + 1) & 0x7f;
+
+ if (prog == BACKGROUND)
+ cquestlin.pc[prog] |= 0x80;
+ else
+ {
+ /* Handle events that happen during FG execution */
+ if (latch == LLATCH_XLATCH)
+ cquestlin.xcnt = cquestlin.y & 0xfff;
+ else
+ {
+ int _xcet;
+ int mux_sel = (BIT(cquestlin.sreg, SREG_DX_DY) << 1) | (BIT(cquestlin.sreg, SREG_DX) ^ BIT(cquestlin.sreg, SREG_DY));
+
+ if (mux_sel == 0)
+ _xcet = !(spf == LSPF_BRES);
+ else if (mux_sel == 1)
+ _xcet = _BIT(cquestlin.fglatch, 1);
+ else if (mux_sel == 2)
+ _xcet = !(cquestlin.gt0reg && (spf == LSPF_BRES));
+ else
+ _xcet = _BIT(cquestlin.fglatch, 0);
+
+ if (!_xcet)
+ cquestlin.xcnt = (cquestlin.xcnt + (_BIT(cquestlin.sreg, SREG_DX) ? 1 : -1)) & 0xfff;
+ }
+
+ if (latch == LLATCH_YLATCH)
+ cquestlin.ycnt = cquestlin.y & 0xfff;
+ else
+ {
+ int _ycet;
+ int mux_sel = (BIT(cquestlin.sreg, SREG_DX_DY) << 1) | (BIT(cquestlin.sreg, SREG_DX) ^ BIT(cquestlin.sreg, SREG_DY));
+
+ if (mux_sel == 0)
+ _ycet = !(cquestlin.gt0reg && (spf == LSPF_BRES));
+ else if (mux_sel == 1)
+ _ycet = _BIT(cquestlin.fglatch, 0);
+ else if (mux_sel == 2)
+ _ycet = !(spf == LSPF_BRES);
+ else
+ _ycet = _BIT(cquestlin.fglatch, 1);
+
+ if (!_ycet)
+ cquestlin.ycnt = (cquestlin.ycnt + (_BIT(cquestlin.sreg, SREG_DY) ? 1 : -1)) & 0xfff;
+ }
+ }
+
+ if (latch == LLATCH_CLATCH)
+ cquestlin.clatch = cquestlin.y & 0x1ff;
+ else if (latch == LLATCH_ZLATCH)
+ cquestlin.zlatch = cquestlin.y & 0xff;
+ else if (latch == LLATCH_FADLATCH)
+ cquestlin.fadlatch = cquestlin.y & 0xfff;
+ else if (latch == LLATCH_BADLATCH)
+ cquestlin.badlatch = cquestlin.y & 0xfff;
+
+ /* What about the SRAM dlatch? */
+ if ( !_BIT(cquestlin.bglatch, 5) )
+ cquestlin.sramdlatch = ((t & 0xf) << 12) | (cquestlin.y & 0x0fff);
+
+ /* BG and FG latches */
+ if (prog == FOREGROUND)
+ {
+ int mux_sel = (!(spf == LSPF_FSTOP) << 1) | !(spf == LSPF_LSTOP);
+ int dowrt;
+ int start_stop;
+
+ /* Handle the stack write and start/stop mux */
+ if (mux_sel == 0)
+ {
+ dowrt = 0;
+ start_stop = 0;
+ }
+ else if (mux_sel == 1)
+ {
+ dowrt = cquestlin.fdxreg ^ BIT(cquestlin.sreg, SREG_DX);
+ start_stop = cquestlin.fdxreg;
+ }
+ else if (mux_sel == 2)
+ {
+ dowrt = BIT(cquestlin.sreg, SREG_LDX) ^ BIT(cquestlin.sreg, SREG_DX);
+ start_stop = BIT(cquestlin.sreg, SREG_DX);
+ }
+ else
+ {
+ dowrt = (spf == LSPF_BRES) && (_BIT(cquestlin.sreg, SREG_DX_DY) || cquestlin.gt0reg);
+ start_stop = BIT(cquestlin.sreg, SREG_DY);
+ }
+
+ cquestlin.fglatch =
+ (!(latch == LLATCH_FADLATCH) << 5)
+ | (dowrt << 4)
+ | (start_stop << 3)
+ | (_pbcs << 2)
+ | (!(spf == LSPF_BRES) << 1)
+ | !(cquestlin.gt0reg && (spf == LSPF_BRES));
+ }
+ else
+ {
+ int _lpwrt = BIT(cquestlin.bglatch, 5);
+
+ cquestlin.bglatch =
+ (!(spf == LSPF_PWRT) << 5)
+ | (_lpwrt << 4)
+ | ((!_lpwrt || (!(spf == LSPF_PWRT) && (latch == LLATCH_BADLATCH))) << 2);
+ }
+
+ /* Clock-in another bit into the sign bit shifter? */
+ if (spf == LSPF_SREG)
+ {
+ /* The sign bit is inverted */
+ cquestlin.sreg = (cquestlin.sreg << 1) | !BIT(cquestlin.f, 11);
+
+ /* Also latch the >0 reg */
+ cquestlin.gt0reg = !(cquestlin.f == 0) && !_BIT(cquestlin.f, 11);
+ }
+ else if (spf == LSPF_FSTRT)
+ {
+ cquestlin.fdxreg = BIT(cquestlin.sreg, 3);
+ }
+
+ /* Load or increment sequence counter? */
+ if (latch == LLATCH_SEQLATCH)
+ {
+ cquestlin.seqcnt = cquestlin.y & 0xfff;
+ }
+ else if (spf == LSPF_BRES)
+ {
+ cquestlin.seqcnt = (cquestlin.seqcnt + 1) & 0xfff;
+
+ /* Also latch the >0 reg */
+ cquestlin.gt0reg = !(cquestlin.f == 0) && !_BIT(cquestlin.f, 11);
+ }
+
+ cquestlin_icount--;
+ cquestlin.clkcnt++;
+ } while (cquestlin_icount > 0);
+
+ return cycles - cquestlin_icount;
+}
+
+
+/***************************************************************************
+ LINE DRAWER DISASSEMBLY HOOK
+***************************************************************************/
+
+static offs_t cquestlin_dasm(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram)
+{
+ static const char* jmps[] =
+ {
+ " ",
+ "JMSB ",
+ "JSEQ ",
+ "JGTZ ",
+ "JC ",
+ "JZ ",
+ "?????",
+ "?????",
+
+ "JUMP ",
+ "JNMSB",
+ "JNSEQ",
+ "JLEZ ",
+ "JNC ",
+ "JNZ ",
+ "?????",
+ "?????",
+ };
+
+ static const char* latches[] =
+ {
+ " ",
+ "SEQLTCH",
+ "XLTCH ",
+ "YLTCH ",
+ "BGLTCH ",
+ "FGLTCH ",
+ "CLTCH ",
+ "ZLTCH ",
+ };
+
+ static const char* spfs[] =
+ {
+ " ",
+ "FSTOP ",
+ "FREG ",
+ "FSTART",
+ "PWRT ",
+ "MULT ",
+ "LSTOP ",
+ "BRES ",
+ };
+
+ UINT64 inst = BIG_ENDIANIZE_INT64(*(UINT64 *)oprom);
+ UINT32 inslow = inst & 0xffffffff;
+ UINT32 inshig = inst >> 32;
+
+ int t = (inshig >> 24) & 0xff;
+ int jmp = (inshig >> 20) & 0xf;
+ int latch = (inshig >> 16) & 0x7;
+ int op = (inshig >> 15) & 0x1;
+ int spf = (inshig >> 12) & 0x7;
+ int b = (inshig >> 8) & 0xf;
+ int a = (inshig >> 4) & 0xf;
+ int i8_6 = (inshig >> 0) & 0x7;
+ int ci = (inslow >> 31) & 0x1;
+ int i5_3 = (inslow >> 28) & 0x7;
+ int _pbcs = (inslow >> 27) & 0x1;
+ int i2_0 = (inslow >> 24) & 0x7;
+
+ sprintf(buffer, "%s %s,%s %x,%x %c %s %.2x %s %s %s %s\n",
+ ins[i5_3],
+ src[i2_0],
+ dst[i8_6],
+ a,
+ b,
+ ci ? 'C' : ' ',
+ jmps[jmp],
+ t,
+ latches[latch],
+ op ? "OP" : " ",
+ _pbcs ? " " : "PB",
+ spfs[spf]);
+
+ return 1 | DASMFLAG_SUPPORTED;
+}
+
+/**************************************************************************
+ * Sound set_info
+ **************************************************************************/
+
+static void cquestsnd_set_info(UINT32 state, cpuinfo *info)
+{
+ switch (state)
+ {
+ /* --- the following bits of info are set as 64-bit signed integers --- */
+ case CPUINFO_INT_PC:
+ case CPUINFO_INT_REGISTER + CQUESTSND_PC: cquestsnd.pc = info->i; break;
+ case CPUINFO_INT_REGISTER + CQUESTSND_Q: cquestsnd.q = info->i; break;
+ case CPUINFO_INT_REGISTER + CQUESTSND_RTNLATCH: cquestsnd.rtnlatch = info->i; break;
+ case CPUINFO_INT_REGISTER + CQUESTSND_ADRCNTR: cquestsnd.adrcntr = info->i; break;
+ case CPUINFO_STR_REGISTER + CQUESTSND_DINLATCH: cquestsnd.dinlatch = info->i; break;
+
+ case CPUINFO_STR_REGISTER + CQUESTSND_RAM0: cquestsnd.ram[0x0] = info->i; break;
+ case CPUINFO_STR_REGISTER + CQUESTSND_RAM1: cquestsnd.ram[0x1] = info->i; break;
+ case CPUINFO_STR_REGISTER + CQUESTSND_RAM2: cquestsnd.ram[0x2] = info->i; break;
+ case CPUINFO_STR_REGISTER + CQUESTSND_RAM3: cquestsnd.ram[0x3] = info->i; break;
+ case CPUINFO_STR_REGISTER + CQUESTSND_RAM4: cquestsnd.ram[0x4] = info->i; break;
+ case CPUINFO_STR_REGISTER + CQUESTSND_RAM5: cquestsnd.ram[0x5] = info->i; break;
+ case CPUINFO_STR_REGISTER + CQUESTSND_RAM6: cquestsnd.ram[0x6] = info->i; break;
+ case CPUINFO_STR_REGISTER + CQUESTSND_RAM7: cquestsnd.ram[0x7] = info->i; break;
+ case CPUINFO_STR_REGISTER + CQUESTSND_RAM8: cquestsnd.ram[0x8] = info->i; break;
+ case CPUINFO_STR_REGISTER + CQUESTSND_RAM9: cquestsnd.ram[0x9] = info->i; break;
+ case CPUINFO_STR_REGISTER + CQUESTSND_RAMA: cquestsnd.ram[0xa] = info->i; break;
+ case CPUINFO_STR_REGISTER + CQUESTSND_RAMB: cquestsnd.ram[0xb] = info->i; break;
+ case CPUINFO_STR_REGISTER + CQUESTSND_RAMC: cquestsnd.ram[0xc] = info->i; break;
+ case CPUINFO_STR_REGISTER + CQUESTSND_RAMD: cquestsnd.ram[0xd] = info->i; break;
+ case CPUINFO_STR_REGISTER + CQUESTSND_RAME: cquestsnd.ram[0xe] = info->i; break;
+ case CPUINFO_STR_REGISTER + CQUESTSND_RAMF: cquestsnd.ram[0xf] = info->i; break;
+ }
+}
+
+/**************************************************************************
+ * Sound get_info
+ **************************************************************************/
+
+void cquestsnd_get_info(UINT32 state, cpuinfo *info)
+{
+ switch (state)
+ {
+ /* --- the following bits of info are returned as 64-bit signed integers --- */
+ case CPUINFO_INT_CONTEXT_SIZE: info->i = sizeof(cquestsnd); break;
+ case CPUINFO_INT_ENDIANNESS: info->i = CPU_IS_BE; break;
+ case CPUINFO_INT_CLOCK_MULTIPLIER: info->i = 1; break;
+ case CPUINFO_INT_CLOCK_DIVIDER: info->i = 1; break;
+ case CPUINFO_INT_MIN_INSTRUCTION_BYTES: info->i = 8; break;
+ case CPUINFO_INT_MAX_INSTRUCTION_BYTES: info->i = 8; break;
+ case CPUINFO_INT_MIN_CYCLES: info->i = 1; break;
+ case CPUINFO_INT_MAX_CYCLES: info->i = 1; break;
+
+ case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 64; break;
+ case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 8; break;
+ case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_PROGRAM: info->i = -3; break;
+ case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_DATA: info->i = 0; break;
+ case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_DATA: info->i = 0; break;
+ case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_DATA: info->i = 0; break;
+ case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_IO: info->i = 0; break;
+ case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_IO: info->i = 0; break;
+ case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_IO: info->i = 0; break;
+
+ case CPUINFO_INT_PC:
+ case CPUINFO_INT_REGISTER + CQUESTSND_PC: info->i = cquestsnd.pc; break;
+ case CPUINFO_INT_REGISTER + CQUESTSND_RTNLATCH: info->i = cquestsnd.rtnlatch; break;
+ case CPUINFO_INT_REGISTER + CQUESTSND_ADRCNTR: info->i = cquestsnd.adrcntr; break;
+
+ /* --- the following bits of info are returned as pointers to data or functions --- */
+ case CPUINFO_PTR_SET_INFO: info->setinfo = cquestsnd_set_info; break;
+ case CPUINFO_PTR_GET_CONTEXT: info->getcontext = cquestsnd_get_context;break;
+ case CPUINFO_PTR_SET_CONTEXT: info->setcontext = cquestsnd_set_context;break;
+ case CPUINFO_PTR_INIT: info->init = cquestsnd_init; break;
+ case CPUINFO_PTR_RESET: info->reset = cquestsnd_reset; break;
+ case CPUINFO_PTR_EXIT: info->exit = cquestsnd_exit; break;
+ case CPUINFO_PTR_EXECUTE: info->execute = cquestsnd_execute; break;
+ case CPUINFO_PTR_BURN: info->burn = NULL; break;
+ case CPUINFO_PTR_DISASSEMBLE: info->disassemble = cquestsnd_dasm; break;
+ case CPUINFO_PTR_INSTRUCTION_COUNTER: info->icount = &cquestsnd_icount; break;
+
+ /* --- the following bits of info are returned as NULL-terminated strings --- */
+ case CPUINFO_STR_NAME: strcpy(info->s, "Sound CPU");break;
+ case CPUINFO_STR_CORE_FAMILY: strcpy(info->s, "Cube Quest"); break;
+ case CPUINFO_STR_CORE_VERSION: strcpy(info->s, "1.0"); break;
+ case CPUINFO_STR_CORE_FILE: strcpy(info->s, __FILE__); break;
+ case CPUINFO_STR_CORE_CREDITS: strcpy(info->s, "Copyright Philip J Bennett"); break;
+
+ case CPUINFO_STR_FLAGS: sprintf(info->s, "......."); break;
+ case CPUINFO_STR_REGISTER + CQUESTSND_PC: sprintf(info->s, "PC: %02X", cquestsnd.pc); break;
+ case CPUINFO_STR_REGISTER + CQUESTSND_Q: sprintf(info->s, "Q: %04X", cquestsnd.q); break;
+ case CPUINFO_STR_REGISTER + CQUESTSND_RTNLATCH: sprintf(info->s, "RTN: %02X", cquestsnd.rtnlatch); break;
+ case CPUINFO_STR_REGISTER + CQUESTSND_ADRCNTR: sprintf(info->s, "CNT: %02X", cquestsnd.adrcntr); break;
+ case CPUINFO_STR_REGISTER + CQUESTSND_DINLATCH: sprintf(info->s, "DIN: %04X", cquestsnd.dinlatch); break;
+ case CPUINFO_STR_REGISTER + CQUESTSND_RAM0: sprintf(info->s, "RAM[0]: %04X", cquestsnd.ram[0x0]); break;
+ case CPUINFO_STR_REGISTER + CQUESTSND_RAM1: sprintf(info->s, "RAM[1]: %04X", cquestsnd.ram[0x1]); break;
+ case CPUINFO_STR_REGISTER + CQUESTSND_RAM2: sprintf(info->s, "RAM[2]: %04X", cquestsnd.ram[0x2]); break;
+ case CPUINFO_STR_REGISTER + CQUESTSND_RAM3: sprintf(info->s, "RAM[3]: %04X", cquestsnd.ram[0x3]); break;
+ case CPUINFO_STR_REGISTER + CQUESTSND_RAM4: sprintf(info->s, "RAM[4]: %04X", cquestsnd.ram[0x4]); break;
+ case CPUINFO_STR_REGISTER + CQUESTSND_RAM5: sprintf(info->s, "RAM[5]: %04X", cquestsnd.ram[0x5]); break;
+ case CPUINFO_STR_REGISTER + CQUESTSND_RAM6: sprintf(info->s, "RAM[6]: %04X", cquestsnd.ram[0x6]); break;
+ case CPUINFO_STR_REGISTER + CQUESTSND_RAM7: sprintf(info->s, "RAM[7]: %04X", cquestsnd.ram[0x7]); break;
+ case CPUINFO_STR_REGISTER + CQUESTSND_RAM8: sprintf(info->s, "RAM[8]: %04X", cquestsnd.ram[0x8]); break;
+ case CPUINFO_STR_REGISTER + CQUESTSND_RAM9: sprintf(info->s, "RAM[9]: %04X", cquestsnd.ram[0x9]); break;
+ case CPUINFO_STR_REGISTER + CQUESTSND_RAMA: sprintf(info->s, "RAM[A]: %04X", cquestsnd.ram[0xa]); break;
+ case CPUINFO_STR_REGISTER + CQUESTSND_RAMB: sprintf(info->s, "RAM[B]: %04X", cquestsnd.ram[0xb]); break;
+ case CPUINFO_STR_REGISTER + CQUESTSND_RAMC: sprintf(info->s, "RAM[C]: %04X", cquestsnd.ram[0xc]); break;
+ case CPUINFO_STR_REGISTER + CQUESTSND_RAMD: sprintf(info->s, "RAM[D]: %04X", cquestsnd.ram[0xd]); break;
+ case CPUINFO_STR_REGISTER + CQUESTSND_RAME: sprintf(info->s, "RAM[E]: %04X", cquestsnd.ram[0xe]); break;
+ case CPUINFO_STR_REGISTER + CQUESTSND_RAMF: sprintf(info->s, "RAM[F]: %04X", cquestsnd.ram[0xf]); break;
+ }
+}
+
+
+/**************************************************************************
+ * Rotate set_info
+ **************************************************************************/
+
+static void cquestrot_set_info(UINT32 state, cpuinfo *info)
+{
+ switch (state)
+ {
+ /* --- the following bits of info are set as 64-bit signed integers --- */
+ case CPUINFO_INT_PC:
+ case CPUINFO_INT_REGISTER + CQUESTROT_PC: cquestrot.pc = info->i; break;
+ case CPUINFO_INT_REGISTER + CQUESTROT_Q: cquestrot.q = info->i; break;
+
+ case CPUINFO_STR_REGISTER + CQUESTROT_RAM0: cquestrot.ram[0x0] = info->i; break;
+ case CPUINFO_STR_REGISTER + CQUESTROT_RAM1: cquestrot.ram[0x1] = info->i; break;
+ case CPUINFO_STR_REGISTER + CQUESTROT_RAM2: cquestrot.ram[0x2] = info->i; break;
+ case CPUINFO_STR_REGISTER + CQUESTROT_RAM3: cquestrot.ram[0x3] = info->i; break;
+ case CPUINFO_STR_REGISTER + CQUESTROT_RAM4: cquestrot.ram[0x4] = info->i; break;
+ case CPUINFO_STR_REGISTER + CQUESTROT_RAM5: cquestrot.ram[0x5] = info->i; break;
+ case CPUINFO_STR_REGISTER + CQUESTROT_RAM6: cquestrot.ram[0x6] = info->i; break;
+ case CPUINFO_STR_REGISTER + CQUESTROT_RAM7: cquestrot.ram[0x7] = info->i; break;
+ case CPUINFO_STR_REGISTER + CQUESTROT_RAM8: cquestrot.ram[0x8] = info->i; break;
+ case CPUINFO_STR_REGISTER + CQUESTROT_RAM9: cquestrot.ram[0x9] = info->i; break;
+ case CPUINFO_STR_REGISTER + CQUESTROT_RAMA: cquestrot.ram[0xa] = info->i; break;
+ case CPUINFO_STR_REGISTER + CQUESTROT_RAMB: cquestrot.ram[0xb] = info->i; break;
+ case CPUINFO_STR_REGISTER + CQUESTROT_RAMC: cquestrot.ram[0xc] = info->i; break;
+ case CPUINFO_STR_REGISTER + CQUESTROT_RAMD: cquestrot.ram[0xd] = info->i; break;
+ case CPUINFO_STR_REGISTER + CQUESTROT_RAME: cquestrot.ram[0xe] = info->i; break;
+ case CPUINFO_STR_REGISTER + CQUESTROT_RAMF: cquestrot.ram[0xf] = info->i; break;
+ case CPUINFO_STR_REGISTER + CQUESTROT_SEQCNT: cquestrot.seqcnt = info->i; break;
+ case CPUINFO_STR_REGISTER + CQUESTROT_DYNADDR: cquestrot.dynaddr = info->i; break;
+ case CPUINFO_STR_REGISTER + CQUESTROT_DYNDATA: cquestrot.dyndata = info->i; break;
+ case CPUINFO_STR_REGISTER + CQUESTROT_YRLATCH: cquestrot.yrlatch = info->i; break;
+ case CPUINFO_STR_REGISTER + CQUESTROT_YDLATCH: cquestrot.ydlatch = info->i; break;
+ case CPUINFO_STR_REGISTER + CQUESTROT_DINLATCH: cquestrot.dinlatch = info->i; break;
+ case CPUINFO_STR_REGISTER + CQUESTROT_DSRCLATCH:cquestrot.dsrclatch = info->i; break;
+ case CPUINFO_STR_REGISTER + CQUESTROT_RSRCLATCH:cquestrot.rsrclatch = info->i; break;
+ }
+}
+
+/**************************************************************************
+ * Rotate get_info
+ **************************************************************************/
+
+void cquestrot_get_info(UINT32 state, cpuinfo *info)
+{
+ switch (state)
+ {
+ /* --- the following bits of info are returned as 64-bit signed integers --- */
+ case CPUINFO_INT_CONTEXT_SIZE: info->i = sizeof(cquestrot); break;
+ case CPUINFO_INT_ENDIANNESS: info->i = CPU_IS_BE; break;
+ case CPUINFO_INT_CLOCK_MULTIPLIER: info->i = 1; break;
+ case CPUINFO_INT_CLOCK_DIVIDER: info->i = 1; break;
+ case CPUINFO_INT_MIN_INSTRUCTION_BYTES: info->i = 8; break;
+ case CPUINFO_INT_MAX_INSTRUCTION_BYTES: info->i = 8; break;
+ case CPUINFO_INT_MIN_CYCLES: info->i = 1; break;
+ case CPUINFO_INT_MAX_CYCLES: info->i = 1; break;
+
+ case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 64; break;
+ case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 9; break;
+ case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_PROGRAM: info->i = -3; break;
+ case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_DATA: info->i = 0; break;
+ case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_DATA: info->i = 0; break;
+ case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_DATA: info->i = 0; break;
+ case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_IO: info->i = 0; break;
+ case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_IO: info->i = 0; break;
+ case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_IO: info->i = 0; break;
+
+ case CPUINFO_INT_PC:
+ case CPUINFO_INT_REGISTER + CQUESTROT_PC: info->i = cquestrot.pc; break;
+
+ /* --- the following bits of info are returned as pointers to data or functions --- */
+ case CPUINFO_PTR_SET_INFO: info->setinfo = cquestrot_set_info; break;
+ case CPUINFO_PTR_GET_CONTEXT: info->getcontext = cquestrot_get_context;break;
+ case CPUINFO_PTR_SET_CONTEXT: info->setcontext = cquestrot_set_context;break;
+ case CPUINFO_PTR_INIT: info->init = cquestrot_init; break;
+ case CPUINFO_PTR_RESET: info->reset = cquestrot_reset; break;
+ case CPUINFO_PTR_EXIT: info->exit = cquestrot_exit; break;
+ case CPUINFO_PTR_EXECUTE: info->execute = cquestrot_execute; break;
+ case CPUINFO_PTR_BURN: info->burn = NULL; break;
+ case CPUINFO_PTR_DISASSEMBLE: info->disassemble = cquestrot_dasm; break;
+ case CPUINFO_PTR_INSTRUCTION_COUNTER: info->icount = &cquestrot_icount; break;
+
+ /* --- the following bits of info are returned as NULL-terminated strings --- */
+ case CPUINFO_STR_NAME: strcpy(info->s, "Rotate CPU");break;
+ case CPUINFO_STR_CORE_FAMILY: strcpy(info->s, "Cube Quest"); break;
+ case CPUINFO_STR_CORE_VERSION: strcpy(info->s, "1.0"); break;
+ case CPUINFO_STR_CORE_FILE: strcpy(info->s, __FILE__); break;
+ case CPUINFO_STR_CORE_CREDITS: strcpy(info->s, "Copyright Philip J Bennett"); break;
+
+ case CPUINFO_STR_FLAGS: sprintf(info->s, "%c%c%c", cquestrot.cflag ? 'C' : '.',
+ cquestrot.vflag ? 'V' : '.',
+ cquestrot.f ? '.' : 'Z'); break;
+ case CPUINFO_STR_REGISTER + CQUESTROT_PC: sprintf(info->s, "PC: %02X", cquestrot.pc); break;
+ case CPUINFO_STR_REGISTER + CQUESTROT_Q: sprintf(info->s, "Q: %04X", cquestrot.q); break;
+ case CPUINFO_STR_REGISTER + CQUESTROT_RAM0: sprintf(info->s, "RAM[0]: %04X", cquestrot.ram[0x0]); break;
+ case CPUINFO_STR_REGISTER + CQUESTROT_RAM1: sprintf(info->s, "RAM[1]: %04X", cquestrot.ram[0x1]); break;
+ case CPUINFO_STR_REGISTER + CQUESTROT_RAM2: sprintf(info->s, "RAM[2]: %04X", cquestrot.ram[0x2]); break;
+ case CPUINFO_STR_REGISTER + CQUESTROT_RAM3: sprintf(info->s, "RAM[3]: %04X", cquestrot.ram[0x3]); break;
+ case CPUINFO_STR_REGISTER + CQUESTROT_RAM4: sprintf(info->s, "RAM[4]: %04X", cquestrot.ram[0x4]); break;
+ case CPUINFO_STR_REGISTER + CQUESTROT_RAM5: sprintf(info->s, "RAM[5]: %04X", cquestrot.ram[0x5]); break;
+ case CPUINFO_STR_REGISTER + CQUESTROT_RAM6: sprintf(info->s, "RAM[6]: %04X", cquestrot.ram[0x6]); break;
+ case CPUINFO_STR_REGISTER + CQUESTROT_RAM7: sprintf(info->s, "RAM[7]: %04X", cquestrot.ram[0x7]); break;
+ case CPUINFO_STR_REGISTER + CQUESTROT_RAM8: sprintf(info->s, "RAM[8]: %04X", cquestrot.ram[0x8]); break;
+ case CPUINFO_STR_REGISTER + CQUESTROT_RAM9: sprintf(info->s, "RAM[9]: %04X", cquestrot.ram[0x9]); break;
+ case CPUINFO_STR_REGISTER + CQUESTROT_RAMA: sprintf(info->s, "RAM[A]: %04X", cquestrot.ram[0xa]); break;
+ case CPUINFO_STR_REGISTER + CQUESTROT_RAMB: sprintf(info->s, "RAM[B]: %04X", cquestrot.ram[0xb]); break;
+ case CPUINFO_STR_REGISTER + CQUESTROT_RAMC: sprintf(info->s, "RAM[C]: %04X", cquestrot.ram[0xc]); break;
+ case CPUINFO_STR_REGISTER + CQUESTROT_RAMD: sprintf(info->s, "RAM[D]: %04X", cquestrot.ram[0xd]); break;
+ case CPUINFO_STR_REGISTER + CQUESTROT_RAME: sprintf(info->s, "RAM[E]: %04X", cquestrot.ram[0xe]); break;
+ case CPUINFO_STR_REGISTER + CQUESTROT_RAMF: sprintf(info->s, "RAM[F]: %04X", cquestrot.ram[0xf]); break;
+ case CPUINFO_STR_REGISTER + CQUESTROT_SEQCNT: sprintf(info->s, "SEQCNT: %01X", cquestrot.seqcnt); break;
+ case CPUINFO_STR_REGISTER + CQUESTROT_DYNADDR: sprintf(info->s, "DYNADDR: %04X", cquestrot.dynaddr); break;
+ case CPUINFO_STR_REGISTER + CQUESTROT_DYNDATA: sprintf(info->s, "DYNDATA: %04X", cquestrot.dyndata); break;
+ case CPUINFO_STR_REGISTER + CQUESTROT_YRLATCH: sprintf(info->s, "YRLATCH: %04X", cquestrot.yrlatch); break;
+ case CPUINFO_STR_REGISTER + CQUESTROT_YDLATCH: sprintf(info->s, "YDLATCH: %04X", cquestrot.ydlatch); break;
+ case CPUINFO_STR_REGISTER + CQUESTROT_DINLATCH: sprintf(info->s, "DINLATCH: %04X", cquestrot.dinlatch); break;
+ case CPUINFO_STR_REGISTER + CQUESTROT_DSRCLATCH:sprintf(info->s, "DSRCLATCH: %04X", cquestrot.dsrclatch); break;
+ case CPUINFO_STR_REGISTER + CQUESTROT_RSRCLATCH:sprintf(info->s, "RSRCLATCH: %04X", cquestrot.rsrclatch); break;
+ case CPUINFO_STR_REGISTER + CQUESTROT_LDADDR: sprintf(info->s, "LDADDR : %04X", cquestrot.lineaddr); break;
+ case CPUINFO_STR_REGISTER + CQUESTROT_LDDATA: sprintf(info->s, "LDDATA : %04X", cquestrot.linedata); break;
+ }
+}
+
+
+/**************************************************************************
+ * Line drawer set_info
+ **************************************************************************/
+
+static void cquestlin_set_info(UINT32 state, cpuinfo *info)
+{
+ switch (state)
+ {
+ /* --- the following bits of info are set as 64-bit signed integers --- */
+ case CPUINFO_INT_PC:
+ case CPUINFO_INT_REGISTER + CQUESTLIN_FGPC: cquestlin.pc[FOREGROUND] = info->i; break;
+ case CPUINFO_INT_REGISTER + CQUESTLIN_BGPC: cquestlin.pc[BACKGROUND] = info->i; break;
+ case CPUINFO_INT_REGISTER + CQUESTLIN_Q: cquestlin.q = info->i; break;
+
+ case CPUINFO_STR_REGISTER + CQUESTLIN_RAM0: cquestlin.ram[0x0] = info->i; break;
+ case CPUINFO_STR_REGISTER + CQUESTLIN_RAM1: cquestlin.ram[0x1] = info->i; break;
+ case CPUINFO_STR_REGISTER + CQUESTLIN_RAM2: cquestlin.ram[0x2] = info->i; break;
+ case CPUINFO_STR_REGISTER + CQUESTLIN_RAM3: cquestlin.ram[0x3] = info->i; break;
+ case CPUINFO_STR_REGISTER + CQUESTLIN_RAM4: cquestlin.ram[0x4] = info->i; break;
+ case CPUINFO_STR_REGISTER + CQUESTLIN_RAM5: cquestlin.ram[0x5] = info->i; break;
+ case CPUINFO_STR_REGISTER + CQUESTLIN_RAM6: cquestlin.ram[0x6] = info->i; break;
+ case CPUINFO_STR_REGISTER + CQUESTLIN_RAM7: cquestlin.ram[0x7] = info->i; break;
+ case CPUINFO_STR_REGISTER + CQUESTLIN_RAM8: cquestlin.ram[0x8] = info->i; break;
+ case CPUINFO_STR_REGISTER + CQUESTLIN_RAM9: cquestlin.ram[0x9] = info->i; break;
+ case CPUINFO_STR_REGISTER + CQUESTLIN_RAMA: cquestlin.ram[0xa] = info->i; break;
+ case CPUINFO_STR_REGISTER + CQUESTLIN_RAMB: cquestlin.ram[0xb] = info->i; break;
+ case CPUINFO_STR_REGISTER + CQUESTLIN_RAMC: cquestlin.ram[0xc] = info->i; break;
+ case CPUINFO_STR_REGISTER + CQUESTLIN_RAMD: cquestlin.ram[0xd] = info->i; break;
+ case CPUINFO_STR_REGISTER + CQUESTLIN_RAME: cquestlin.ram[0xe] = info->i; break;
+ case CPUINFO_STR_REGISTER + CQUESTLIN_RAMF: cquestlin.ram[0xf] = info->i; break;
+ }
+}
+
+/**************************************************************************
+ * Line drawer get_info
+ **************************************************************************/
+
+void cquestlin_get_info(UINT32 state, cpuinfo *info)
+{
+ switch (state)
+ {
+ /* --- the following bits of info are returned as 64-bit signed integers --- */
+ case CPUINFO_INT_CONTEXT_SIZE: info->i = sizeof(cquestlin); break;
+ case CPUINFO_INT_ENDIANNESS: info->i = CPU_IS_BE; break;
+ case CPUINFO_INT_CLOCK_MULTIPLIER: info->i = 1; break;
+ case CPUINFO_INT_CLOCK_DIVIDER: info->i = 1; break;
+ case CPUINFO_INT_MIN_INSTRUCTION_BYTES: info->i = 8; break;
+ case CPUINFO_INT_MAX_INSTRUCTION_BYTES: info->i = 8; break;
+ case CPUINFO_INT_MIN_CYCLES: info->i = 1; break;
+ case CPUINFO_INT_MAX_CYCLES: info->i = 1; break;
+
+ case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 64; break;
+ case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 8; break;
+ case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_PROGRAM: info->i = -3; break;
+ case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_DATA: info->i = 0; break;
+ case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_DATA: info->i = 0; break;
+ case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_DATA: info->i = 0; break;
+ case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_IO: info->i = 0; break;
+ case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_IO: info->i = 0; break;
+ case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_IO: info->i = 0; break;
+
+ case CPUINFO_INT_PC:
+ case CPUINFO_INT_REGISTER + CQUESTLIN_FGPC: info->i = cquestlin.pc[cquestlin.clkcnt & 3 ? BACKGROUND : FOREGROUND]; break;
+
+ /* --- the following bits of info are returned as pointers to data or functions --- */
+ case CPUINFO_PTR_SET_INFO: info->setinfo = cquestlin_set_info; break;
+ case CPUINFO_PTR_GET_CONTEXT: info->getcontext = cquestlin_get_context;break;
+ case CPUINFO_PTR_SET_CONTEXT: info->setcontext = cquestlin_set_context;break;
+ case CPUINFO_PTR_INIT: info->init = cquestlin_init; break;
+ case CPUINFO_PTR_RESET: info->reset = cquestlin_reset; break;
+ case CPUINFO_PTR_EXIT: info->exit = cquestlin_exit; break;
+ case CPUINFO_PTR_EXECUTE: info->execute = cquestlin_execute; break;
+ case CPUINFO_PTR_BURN: info->burn = NULL; break;
+ case CPUINFO_PTR_DISASSEMBLE: info->disassemble = cquestlin_dasm; break;
+ case CPUINFO_PTR_INSTRUCTION_COUNTER: info->icount = &cquestlin_icount; break;
+
+ /* --- the following bits of info are returned as NULL-terminated strings --- */
+ case CPUINFO_STR_NAME: strcpy(info->s, "Line CPU"); break;
+ case CPUINFO_STR_CORE_FAMILY: strcpy(info->s, "Cube Quest"); break;
+ case CPUINFO_STR_CORE_VERSION: strcpy(info->s, "1.0"); break;
+ case CPUINFO_STR_CORE_FILE: strcpy(info->s, __FILE__); break;
+ case CPUINFO_STR_CORE_CREDITS: strcpy(info->s, "Copyright Philip J Bennett"); break;
+
+ case CPUINFO_STR_FLAGS: sprintf(info->s, "%c%c%c|%cG", cquestlin.cflag ? 'C' : '.',
+ cquestlin.vflag ? 'V' : '.',
+ cquestlin.f ? '.' : 'Z',
+ cquestlin.clkcnt & 3 ? 'B' : 'F'); break;
+ case CPUINFO_STR_REGISTER + CQUESTLIN_FGPC: sprintf(info->s, "FPC: %02X", cquestlin.pc[FOREGROUND]); break;
+ case CPUINFO_STR_REGISTER + CQUESTLIN_BGPC: sprintf(info->s, "BPC: %02X", cquestlin.pc[BACKGROUND]); break;
+ case CPUINFO_STR_REGISTER + CQUESTLIN_Q: sprintf(info->s, "Q: %04X", cquestlin.q); break;
+ case CPUINFO_STR_REGISTER + CQUESTLIN_RAM0: sprintf(info->s, "RAM[0]: %04X", cquestlin.ram[0x0]); break;
+ case CPUINFO_STR_REGISTER + CQUESTLIN_RAM1: sprintf(info->s, "RAM[1]: %04X", cquestlin.ram[0x1]); break;
+ case CPUINFO_STR_REGISTER + CQUESTLIN_RAM2: sprintf(info->s, "RAM[2]: %04X", cquestlin.ram[0x2]); break;
+ case CPUINFO_STR_REGISTER + CQUESTLIN_RAM3: sprintf(info->s, "RAM[3]: %04X", cquestlin.ram[0x3]); break;
+ case CPUINFO_STR_REGISTER + CQUESTLIN_RAM4: sprintf(info->s, "RAM[4]: %04X", cquestlin.ram[0x4]); break;
+ case CPUINFO_STR_REGISTER + CQUESTLIN_RAM5: sprintf(info->s, "RAM[5]: %04X", cquestlin.ram[0x5]); break;
+ case CPUINFO_STR_REGISTER + CQUESTLIN_RAM6: sprintf(info->s, "RAM[6]: %04X", cquestlin.ram[0x6]); break;
+ case CPUINFO_STR_REGISTER + CQUESTLIN_RAM7: sprintf(info->s, "RAM[7]: %04X", cquestlin.ram[0x7]); break;
+ case CPUINFO_STR_REGISTER + CQUESTLIN_RAM8: sprintf(info->s, "RAM[8]: %04X", cquestlin.ram[0x8]); break;
+ case CPUINFO_STR_REGISTER + CQUESTLIN_RAM9: sprintf(info->s, "RAM[9]: %04X", cquestlin.ram[0x9]); break;
+ case CPUINFO_STR_REGISTER + CQUESTLIN_RAMA: sprintf(info->s, "RAM[A]: %04X", cquestlin.ram[0xa]); break;
+ case CPUINFO_STR_REGISTER + CQUESTLIN_RAMB: sprintf(info->s, "RAM[B]: %04X", cquestlin.ram[0xb]); break;
+ case CPUINFO_STR_REGISTER + CQUESTLIN_RAMC: sprintf(info->s, "RAM[C]: %04X", cquestlin.ram[0xc]); break;
+ case CPUINFO_STR_REGISTER + CQUESTLIN_RAMD: sprintf(info->s, "RAM[D]: %04X", cquestlin.ram[0xd]); break;
+ case CPUINFO_STR_REGISTER + CQUESTLIN_RAME: sprintf(info->s, "RAM[E]: %04X", cquestlin.ram[0xe]); break;
+ case CPUINFO_STR_REGISTER + CQUESTLIN_RAMF: sprintf(info->s, "RAM[F]: %04X", cquestlin.ram[0xf]); break;
+
+ case CPUINFO_STR_REGISTER + CQUESTLIN_FADLATCH: sprintf(info->s, "FADDR: %04X", cquestlin.fadlatch); break;
+ case CPUINFO_STR_REGISTER + CQUESTLIN_BADLATCH: sprintf(info->s, "BADDR: %04X", cquestlin.badlatch); break;
+ case CPUINFO_STR_REGISTER + CQUESTLIN_SREG: sprintf(info->s, "SREG: %04X", cquestlin.sreg); break;
+ case CPUINFO_STR_REGISTER + CQUESTLIN_XCNT: sprintf(info->s, "XCNT: %03X", cquestlin.xcnt); break;
+ case CPUINFO_STR_REGISTER + CQUESTLIN_YCNT: sprintf(info->s, "YCNT: %03X", cquestlin.ycnt); break;
+ case CPUINFO_STR_REGISTER + CQUESTLIN_CLATCH: sprintf(info->s, "CLATCH: %04X", cquestlin.clatch); break;
+ case CPUINFO_STR_REGISTER + CQUESTLIN_ZLATCH: sprintf(info->s, "ZLATCH: %04X", cquestlin.zlatch); break;
+ }
+}
diff --git a/src/emu/cpu/cubeqcpu/cubeqcpu.h b/src/emu/cpu/cubeqcpu/cubeqcpu.h
new file mode 100644
index 00000000000..037424f4da1
--- /dev/null
+++ b/src/emu/cpu/cubeqcpu/cubeqcpu.h
@@ -0,0 +1,146 @@
+/***************************************************************************
+
+ cubeqcpu.h
+ Interface file for the Cube Quest CPUs
+ Written by Phil Bennett
+
+***************************************************************************/
+
+#ifndef _CUBEQCPU_H
+#define _CUBEQCPU_H
+
+#include "cpuintrf.h"
+
+
+/***************************************************************************
+ COMPILE-TIME DEFINITIONS
+***************************************************************************/
+
+
+/***************************************************************************
+ GLOBAL CONSTANTS
+***************************************************************************/
+
+
+/***************************************************************************
+ REGISTER ENUMERATION
+***************************************************************************/
+
+enum
+{
+ CQUESTSND_PC = 1,
+ CQUESTSND_Q,
+ CQUESTSND_RAM0,
+ CQUESTSND_RAM1,
+ CQUESTSND_RAM2,
+ CQUESTSND_RAM3,
+ CQUESTSND_RAM4,
+ CQUESTSND_RAM5,
+ CQUESTSND_RAM6,
+ CQUESTSND_RAM7,
+ CQUESTSND_RAM8,
+ CQUESTSND_RAM9,
+ CQUESTSND_RAMA,
+ CQUESTSND_RAMB,
+ CQUESTSND_RAMC,
+ CQUESTSND_RAMD,
+ CQUESTSND_RAME,
+ CQUESTSND_RAMF,
+ CQUESTSND_RTNLATCH,
+ CQUESTSND_ADRCNTR,
+ CQUESTSND_DINLATCH,
+};
+
+enum
+{
+ CQUESTROT_PC = 1,
+ CQUESTROT_Q,
+ CQUESTROT_RAM0,
+ CQUESTROT_RAM1,
+ CQUESTROT_RAM2,
+ CQUESTROT_RAM3,
+ CQUESTROT_RAM4,
+ CQUESTROT_RAM5,
+ CQUESTROT_RAM6,
+ CQUESTROT_RAM7,
+ CQUESTROT_RAM8,
+ CQUESTROT_RAM9,
+ CQUESTROT_RAMA,
+ CQUESTROT_RAMB,
+ CQUESTROT_RAMC,
+ CQUESTROT_RAMD,
+ CQUESTROT_RAME,
+ CQUESTROT_RAMF,
+ CQUESTROT_SEQCNT,
+ CQUESTROT_DYNADDR,
+ CQUESTROT_DYNDATA,
+ CQUESTROT_YRLATCH,
+ CQUESTROT_YDLATCH,
+ CQUESTROT_DINLATCH,
+ CQUESTROT_DSRCLATCH,
+ CQUESTROT_RSRCLATCH,
+ CQUESTROT_LDADDR,
+ CQUESTROT_LDDATA,
+};
+
+enum
+{
+ CQUESTLIN_FGPC = 1,
+ CQUESTLIN_BGPC,
+ CQUESTLIN_Q,
+ CQUESTLIN_RAM0,
+ CQUESTLIN_RAM1,
+ CQUESTLIN_RAM2,
+ CQUESTLIN_RAM3,
+ CQUESTLIN_RAM4,
+ CQUESTLIN_RAM5,
+ CQUESTLIN_RAM6,
+ CQUESTLIN_RAM7,
+ CQUESTLIN_RAM8,
+ CQUESTLIN_RAM9,
+ CQUESTLIN_RAMA,
+ CQUESTLIN_RAMB,
+ CQUESTLIN_RAMC,
+ CQUESTLIN_RAMD,
+ CQUESTLIN_RAME,
+ CQUESTLIN_RAMF,
+ CQUESTLIN_FADLATCH,
+ CQUESTLIN_BADLATCH,
+ CQUESTLIN_SREG,
+ CQUESTLIN_XCNT,
+ CQUESTLIN_YCNT,
+ CQUESTLIN_CLATCH,
+ CQUESTLIN_ZLATCH,
+};
+
+
+/***************************************************************************
+ CONFIGURATION STRUCTURE
+***************************************************************************/
+
+typedef struct _cubeqst_snd_config cubeqst_snd_config;
+struct _cubeqst_snd_config
+{
+ void (*dac_w)(UINT16);
+ const char *sound_data_region;
+
+};
+
+/***************************************************************************
+ PUBLIC FUNCTIONS
+***************************************************************************/
+
+extern READ16_HANDLER( read_sndram );
+extern WRITE16_HANDLER( write_sndram );
+
+extern READ16_HANDLER( read_rotram );
+extern WRITE16_HANDLER( write_rotram );
+
+void cubeqcpu_swap_line_banks(void);
+
+void clear_stack(void);
+UINT8 get_ptr_ram_val(int i);
+UINT32* get_stack_ram(void);
+
+
+#endif /* _CUBEQCPU_H */
diff --git a/src/emu/cpuexec.h b/src/emu/cpuexec.h
index 3d2a6724c45..f51a0cd2b56 100644
--- a/src/emu/cpuexec.h
+++ b/src/emu/cpuexec.h
@@ -147,6 +147,9 @@ enum _cpu_type
CPU_UPD78C06,
CPU_JAGUARGPU,
CPU_JAGUARDSP,
+ CPU_CQUESTSND,
+ CPU_CQUESTROT,
+ CPU_CQUESTLIN,
CPU_R3000BE,
CPU_R3000LE,
CPU_R3041BE,
diff --git a/src/emu/cpuintrf.c b/src/emu/cpuintrf.c
index d81825d94e7..574ee4be21f 100644
--- a/src/emu/cpuintrf.c
+++ b/src/emu/cpuintrf.c
@@ -119,6 +119,9 @@ void upd78c05_get_info(UINT32 state, cpuinfo *info);
void upd78c06_get_info(UINT32 state, cpuinfo *info);
void jaguargpu_get_info(UINT32 state, cpuinfo *info);
void jaguardsp_get_info(UINT32 state, cpuinfo *info);
+void cquestsnd_get_info(UINT32 state, cpuinfo *info);
+void cquestrot_get_info(UINT32 state, cpuinfo *info);
+void cquestlin_get_info(UINT32 state, cpuinfo *info);
void r3000be_get_info(UINT32 state, cpuinfo *info);
void r3000le_get_info(UINT32 state, cpuinfo *info);
void r3041be_get_info(UINT32 state, cpuinfo *info);
@@ -575,6 +578,11 @@ static const struct
{ CPU_JAGUARGPU, jaguargpu_get_info },
{ CPU_JAGUARDSP, jaguardsp_get_info },
#endif
+#if (HAS_CUBEQCPU)
+ { CPU_CQUESTSND, cquestsnd_get_info },
+ { CPU_CQUESTROT, cquestrot_get_info },
+ { CPU_CQUESTLIN, cquestlin_get_info },
+#endif
#if (HAS_R3000)
{ CPU_R3000BE, r3000be_get_info },
{ CPU_R3000LE, r3000le_get_info },
diff --git a/src/emu/machine/laserdsc.c b/src/emu/machine/laserdsc.c
index 73d4c5ff149..67cf4c0e5ab 100644
--- a/src/emu/machine/laserdsc.c
+++ b/src/emu/machine/laserdsc.c
@@ -15,6 +15,7 @@
#include "profiler.h"
#include "streams.h"
#include "vbiparse.h"
+#include "config.h"
#include "sound/custom.h"
@@ -78,6 +79,7 @@ typedef enum _playstate playstate;
#define AUDIO_CH2_ENABLE 0x02
#define AUDIO_EXPLICIT_MUTE 0x04
#define AUDIO_IMPLICIT_MUTE 0x08
+#define AUDIO_SQUELCH_OVERRIDE 0x10
#define VIDEO_ENABLE 0x01
#define VIDEO_EXPLICIT_MUTE 0x02
@@ -108,6 +110,13 @@ typedef enum _playstate playstate;
#define PR8210_STEP_SPEED (PLAY_SPEED / 7)
#define PR8210_SEARCH_SPEED INT_TO_FRAC(5000)
+/* Simutrek Special specific states */
+#define SIMUTREK_SCAN_SPEED PR8210_SCAN_SPEED
+#define SIMUTREK_FAST_SPEED PR8210_FAST_SPEED
+#define SIMUTREK_SLOW_SPEED PR8210_SLOW_SPEED
+#define SIMUTREK_STEP_SPEED PR8210_STEP_SPEED
+#define SIMUTREK_SEARCH_SPEED PR8210_SEARCH_SPEED
+
/* Pioneer LD-V1000 specific states */
#define LDV1000_MODE_STATUS 0
#define LDV1000_MODE_GET_FRAME 1
@@ -162,6 +171,21 @@ struct _pr8210_info
UINT8 seekstate; /* state of the seek command */
};
+/* Simutrek-specific data */
+typedef struct _simutrek_info simutrek_info;
+struct _simutrek_info
+{
+ UINT8 mode; /* current mode */
+ UINT8 lastcommand; /* last command byte received */
+ UINT16 accumulator; /* bit accumulator */
+ attotime lastbittime; /* time of last bit received */
+ attotime firstbittime; /* time of first bit in command */
+ UINT8 seekstate; /* state of the seek command */
+ UINT8 cmdcnt; /* counter for multi-byte command */
+ UINT8 cmdbytes[3]; /* storage for multi-byte command */
+ void (*cmd_ack_callback)(void); /* callback to clear game command write flag */
+};
+
/* LD-V1000-specific data */
typedef struct _ldv1000_info ldv1000_info;
@@ -201,6 +225,9 @@ struct _vp932_info
typedef struct _laserdisc_state laserdisc_state;
struct _laserdisc_state
{
+ /* general config */
+ laserdisc_config config; /* copy of the inline config */
+
/* disc parameters */
chd_file * disc; /* handle to the disc itself */
av_codec_decompress_config avconfig; /* decompression configuration */
@@ -218,7 +245,6 @@ struct _laserdisc_state
bitmap_t videotarget; /* fake target bitmap for decompression */
/* audio data */
- laserdisc_audio_func audiocallback; /* callback function for audio processing */
INT16 * audiobuffer[2]; /* buffer for audio samples */
UINT32 audiobufsize; /* size of buffer */
UINT32 audiobufin; /* input index */
@@ -234,7 +260,6 @@ struct _laserdisc_state
int last_chapter; /* last seen chapter number */
/* core states */
- UINT8 type; /* laserdisc type */
playstate state; /* current playback state */
UINT8 video; /* video state: bit 0 = on/off */
UINT8 audio; /* audio state: bit 0 = audio 1, bit 1 = audio 2 */
@@ -262,6 +287,14 @@ struct _laserdisc_state
INT32 curfracspeed; /* current speed the head is moving */
INT32 curfractrack; /* current track */
INT32 targetframe; /* target frame (0 means no target) */
+
+ /* video updating */
+ UINT8 videoenable; /* is video enabled? */
+ render_texture * videotex; /* texture for the video */
+ UINT8 overenable; /* is the overlay enabled? */
+ bitmap_t * overbitmap[2]; /* overlay bitmaps */
+ int overindex; /* index of the overlay bitmap */
+ render_texture * overtex; /* texture for the overlay */
/* debugging */
char text[100]; /* buffer for the state */
@@ -279,6 +312,7 @@ struct _laserdisc_state
{
pr7820_info pr7820; /* PR-7820-specific info */
pr8210_info pr8210; /* PR-8210-specific info */
+ simutrek_info simutrek; /* Simutrek-specific info */
ldv1000_info ldv1000; /* LD-V1000-specific info */
ldp1450_info ldp1450; /* LDP-1450-specific info */
vp932_info vp932; /* 22VP932-specific info */
@@ -308,6 +342,8 @@ static void fake_metadata(UINT32 track, UINT8 which, vbi_metadata *metadata);
static void render_display(UINT16 *videodata, UINT32 rowpixels, UINT32 width, int frame);
static void *custom_start(int clock, const custom_sound_interface *config);
static void custom_stream_callback(void *param, stream_sample_t **inputs, stream_sample_t **outputs, int samples);
+static void configuration_load(running_machine *machine, int config_type, xml_data_node *parentnode);
+static void configuration_save(running_machine *machine, int config_type, xml_data_node *parentnode);
/* Pioneer PR-7820 implementation */
static void pr7820_init(laserdisc_state *ld);
@@ -322,6 +358,12 @@ static void pr8210_soft_reset(laserdisc_state *ld);
static void pr8210_command(laserdisc_state *ld);
static void pr8210_control_w(laserdisc_state *ld, UINT8 data);
+/* Simutrek modified players implementation */
+static void simutrek_init(laserdisc_state *ld);
+static void simutrek_soft_reset(laserdisc_state *ld);
+static void simutrek_data_w(laserdisc_state *ld, UINT8 prev, UINT8 data);
+static UINT8 simutrek_status_r(laserdisc_state *ld);
+
/* Pioneer LDV-1000 implementation */
static void ldv1000_init(laserdisc_state *ld);
static void ldv1000_soft_reset(laserdisc_state *ld);
@@ -513,6 +555,8 @@ INLINE int audio_channel_active(laserdisc_state *ld, int channel)
default:
break;
}
+ if (ld->audio & AUDIO_SQUELCH_OVERRIDE)
+ result = 1;
return result;
}
@@ -881,7 +925,7 @@ void laserdisc_vsync(const device_config *device)
}
/* flush any audio before we read more */
- if (sndti_exists(SOUND_CUSTOM, ld->audiocustom))
+ if (ld->audiocustom != -1)
{
sound_token *token = custom_get_token(ld->audiocustom);
stream_update(token->stream);
@@ -1374,8 +1418,8 @@ static void process_track_data(const device_config *device)
}
/* pass the audio to the callback */
- if (ld->audiocallback != NULL)
- (*ld->audiocallback)(device, ld->samplerate, ld->audiocursamples, ld->avconfig.audio[0], ld->avconfig.audio[1]);
+ if (ld->config.audio != NULL)
+ (*ld->config.audio)(device, ld->samplerate, ld->audiocursamples, ld->avconfig.audio[0], ld->avconfig.audio[1]);
/* shift audio data if we read it into the beginning of the buffer */
if (ld->audiocursamples != 0 && ld->audiobufin != 0)
@@ -1565,6 +1609,253 @@ static void custom_stream_callback(void *param, stream_sample_t **inputs, stream
/***************************************************************************
+ CONFIG SETTINGS ACCESS
+***************************************************************************/
+
+/*-------------------------------------------------
+ configuration_load - read and apply data from
+ the configuration file
+-------------------------------------------------*/
+
+static void configuration_load(running_machine *machine, int config_type, xml_data_node *parentnode)
+{
+ xml_data_node *overnode;
+ xml_data_node *ldnode;
+
+ /* we only care about game files */
+ if (config_type != CONFIG_TYPE_GAME)
+ return;
+
+ /* might not have any data */
+ if (parentnode == NULL)
+ return;
+
+ /* iterate over overlay nodes */
+ for (ldnode = xml_get_sibling(parentnode->child, "device"); ldnode != NULL; ldnode = xml_get_sibling(ldnode->next, "device"))
+ {
+ const char *devtag = xml_get_attribute_string(ldnode, "tag", "");
+ const device_config *device = device_list_find_by_tag(machine->config->devicelist, LASERDISC, devtag);
+ if (device != NULL)
+ {
+ laserdisc_state *ld = get_safe_token(device);
+
+ /* handle the overlay node */
+ overnode = xml_get_sibling(ldnode->child, "overlay");
+ if (overnode != NULL)
+ {
+ /* fetch positioning controls */
+ ld->config.overposx = xml_get_attribute_float(overnode, "hoffset", ld->config.overposx);
+ ld->config.overscalex = xml_get_attribute_float(overnode, "hstretch", ld->config.overscalex);
+ ld->config.overposy = xml_get_attribute_float(overnode, "voffset", ld->config.overposy);
+ ld->config.overscaley = xml_get_attribute_float(overnode, "vstretch", ld->config.overscaley);
+ }
+ }
+ }
+}
+
+
+/*-------------------------------------------------
+ configuration_save - save data to the
+ configuration file
+-------------------------------------------------*/
+
+static void configuration_save(running_machine *machine, int config_type, xml_data_node *parentnode)
+{
+ const device_config *device;
+
+ /* we only care about game files */
+ if (config_type != CONFIG_TYPE_GAME)
+ return;
+
+ /* iterate over disc devices */
+ for (device = device_list_first(machine->config->devicelist, LASERDISC); device != NULL; device = device_list_next(device, LASERDISC))
+ {
+ laserdisc_config *origconfig = device->inline_config;
+ laserdisc_state *ld = get_safe_token(device);
+ xml_data_node *overnode;
+ xml_data_node *ldnode;
+
+ /* create a node */
+ ldnode = xml_add_child(parentnode, "device", NULL);
+ if (ldnode != NULL)
+ {
+ int changed = FALSE;
+
+ /* output the basics */
+ xml_set_attribute(ldnode, "tag", device->tag);
+
+ /* add an overlay node */
+ overnode = xml_add_child(ldnode, "overlay", NULL);
+ if (overnode != NULL)
+ {
+ /* output the positioning controls */
+ if (ld->config.overposx != origconfig->overposx)
+ {
+ xml_set_attribute_float(overnode, "hoffset", ld->config.overposx);
+ changed = TRUE;
+ }
+
+ if (ld->config.overscalex != origconfig->overscalex)
+ {
+ xml_set_attribute_float(overnode, "hstretch", ld->config.overscalex);
+ changed = TRUE;
+ }
+
+ if (ld->config.overposy != origconfig->overposy)
+ {
+ xml_set_attribute_float(overnode, "voffset", ld->config.overposy);
+ changed = TRUE;
+ }
+
+ if (ld->config.overscaley != origconfig->overscaley)
+ {
+ xml_set_attribute_float(overnode, "vstretch", ld->config.overscaley);
+ changed = TRUE;
+ }
+ }
+
+ /* if nothing changed, kill the node */
+ if (!changed)
+ xml_delete_node(ldnode);
+ }
+ }
+}
+
+
+
+/***************************************************************************
+ VIDEO INTERFACE
+***************************************************************************/
+
+/*-------------------------------------------------
+ laserdisc_video_enable - enable/disable the
+ video
+-------------------------------------------------*/
+
+void laserdisc_video_enable(const device_config *device, int enable)
+{
+ laserdisc_state *ld = get_safe_token(device);
+ ld->videoenable = enable;
+}
+
+
+/*-------------------------------------------------
+ laserdisc_video_enable - enable/disable the
+ video
+-------------------------------------------------*/
+
+void laserdisc_overlay_enable(const device_config *device, int enable)
+{
+ laserdisc_state *ld = get_safe_token(device);
+ ld->overenable = enable;
+}
+
+
+/*-------------------------------------------------
+ video update callback
+-------------------------------------------------*/
+
+VIDEO_UPDATE( laserdisc )
+{
+ const device_config *laserdisc = device_list_first(screen->machine->config->devicelist, LASERDISC);
+ if (laserdisc != NULL)
+ {
+ laserdisc_state *ld = laserdisc->token;
+ bitmap_t *overbitmap = ld->overbitmap[ld->overindex];
+ bitmap_t *vidbitmap = NULL;
+
+ /* handle the overlay if present */
+ if (overbitmap != NULL)
+ {
+ rectangle clip = *cliprect;
+
+ /* scale the cliprect to the overlay size */
+ clip.min_x = 0;
+ clip.max_x = ld->config.overwidth - 1;
+ clip.min_y = cliprect->min_y * overbitmap->height / bitmap->height;
+ clip.max_y = (cliprect->max_y + 1) * overbitmap->height / bitmap->height - 1;
+
+ /* call the callback */
+ if (ld->config.overupdate != NULL)
+ (*ld->config.overupdate)(screen, overbitmap, &clip);
+ }
+
+ /* if this is the last update, do the rendering */
+ if (cliprect->max_y == video_screen_get_visible_area(screen)->max_y)
+ {
+ float x0, y0, x1, y1;
+
+ /* update the texture with the overlay contents */
+ if (overbitmap != NULL)
+ {
+ if (overbitmap->format == BITMAP_FORMAT_INDEXED16)
+ render_texture_set_bitmap(ld->overtex, overbitmap, &ld->config.overclip, 0, TEXFORMAT_PALETTEA16);
+ else if (overbitmap->format == BITMAP_FORMAT_RGB32)
+ render_texture_set_bitmap(ld->overtex, overbitmap, &ld->config.overclip, 0, TEXFORMAT_ARGB32);
+ }
+
+ /* get the laserdisc video */
+ laserdisc_get_video(laserdisc, &vidbitmap);
+ if (vidbitmap != NULL)
+ render_texture_set_bitmap(ld->videotex, vidbitmap, NULL, 0, TEXFORMAT_YUY16);
+
+ /* reset the screen contents */
+ render_container_empty(render_container_get_screen(screen));
+
+ /* add the video texture */
+ if (ld->videoenable)
+ render_screen_add_quad(screen, 0.0f, 0.0f, 1.0f, 1.0f, MAKE_ARGB(0xff,0xff,0xff,0xff), ld->videotex, PRIMFLAG_BLENDMODE(BLENDMODE_NONE) | PRIMFLAG_SCREENTEX(1));
+
+ /* add the overlay */
+ if (ld->overenable && overbitmap != NULL)
+ {
+ x0 = 0.5f - 0.5f * ld->config.overscalex + ld->config.overposx;
+ y0 = 0.5f - 0.5f * ld->config.overscaley + ld->config.overposy;
+ x1 = x0 + ld->config.overscalex;
+ y1 = y0 + ld->config.overscaley;
+ render_screen_add_quad(screen, x0, y0, x1, y1, MAKE_ARGB(0xff,0xff,0xff,0xff), ld->overtex, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_SCREENTEX(1));
+ }
+
+ /* swap to the next bitmap */
+ ld->overindex = (ld->overindex + 1) % ARRAY_LENGTH(ld->overbitmap);
+ }
+ }
+
+ return 0;
+}
+
+
+
+/***************************************************************************
+ CONFIGURATION
+***************************************************************************/
+
+/*-------------------------------------------------
+ laserdisc_get_config - return a copy of the
+ current live configuration settings
+-------------------------------------------------*/
+
+void laserdisc_get_config(const device_config *device, laserdisc_config *config)
+{
+ laserdisc_state *ld = get_safe_token(device);
+ *config = ld->config;
+}
+
+
+/*-------------------------------------------------
+ laserdisc_get_config - change the current live
+ configuration settings
+-------------------------------------------------*/
+
+void laserdisc_set_config(const device_config *device, const laserdisc_config *config)
+{
+ laserdisc_state *ld = get_safe_token(device);
+ ld->config = *config;
+}
+
+
+
+/***************************************************************************
DEVICE INTERFACE
***************************************************************************/
@@ -1583,14 +1874,30 @@ static DEVICE_START( laserdisc )
chd_error err;
/* copy config data to the live state */
- ld->type = config->type;
- ld->audiocallback = config->audio;
+ ld->config = *config;
+ if (ld->config.overclip.max_x == ld->config.overclip.min_x || ld->config.overclip.max_y == ld->config.overclip.min_y)
+ {
+ ld->config.overclip.min_x = ld->config.overclip.min_y = 0;
+ ld->config.overclip.max_x = ld->config.overwidth - 1;
+ ld->config.overclip.max_y = ld->config.overheight - 1;
+ }
+ if (ld->config.overscalex == 0)
+ ld->config.overscalex = 1.0f;
+ if (ld->config.overscaley == 0)
+ ld->config.overscaley = 1.0f;
/* find the disc */
ld->disc = get_disk_handle(device->tag);
+ ld->audiocustom = 0;
for (sndnum = 0; sndnum < MAX_SOUND; sndnum++)
+ {
if (device->machine->config->sound[sndnum].tag != NULL && strcmp(device->machine->config->sound[sndnum].tag, device->tag) == 0)
- sndnum_to_sndti(sndnum, &ld->audiocustom);
+ break;
+ if (device->machine->config->sound[sndnum].type == SOUND_CUSTOM)
+ ld->audiocustom++;
+ }
+ if (sndnum == MAX_SOUND)
+ ld->audiocustom = -1;
/* get the disc metadata and extract the ld */
if (ld->disc != NULL)
@@ -1622,8 +1929,9 @@ static DEVICE_START( laserdisc )
ld->videoframe[index] = auto_bitmap_alloc(width, height * 2, BITMAP_FORMAT_YUY16);
ld->videovisframe[index] = auto_malloc(sizeof(*ld->videovisframe[index]));
*ld->videovisframe[index] = *ld->videoframe[index];
- ld->videovisframe[index]->base = BITMAP_ADDR16(ld->videovisframe[index], 44, 0);
+ ld->videovisframe[index]->base = BITMAP_ADDR16(ld->videovisframe[index], 44, ld->videoframe[index]->width * 8 / 720);
ld->videovisframe[index]->height -= 44;
+ ld->videovisframe[index]->width -= 2 * ld->videoframe[index]->width * 8 / 720;
fillbitmap_yuy16(ld->videoframe[index], 40, 109, 240);
}
ld->emptyframe = auto_bitmap_alloc(width, height * 2, BITMAP_FORMAT_YUY16);
@@ -1636,6 +1944,26 @@ static DEVICE_START( laserdisc )
ld->audiobuffer[0] = auto_malloc(ld->audiobufsize * sizeof(ld->audiobuffer[0][0]));
ld->audiobuffer[1] = auto_malloc(ld->audiobufsize * sizeof(ld->audiobuffer[1][0]));
ld->samplerate = rate;
+
+ /* allocate texture for rendering */
+ ld->videoenable = TRUE;
+ ld->videotex = render_texture_alloc(NULL, NULL);
+ if (ld->videotex == NULL)
+ fatalerror("Out of memory allocating video texture");
+
+ /* allocate overlay */
+ if (ld->config.overwidth > 0 && ld->config.overheight > 0 && ld->config.overupdate != NULL)
+ {
+ ld->overenable = TRUE;
+ ld->overbitmap[0] = auto_bitmap_alloc(ld->config.overwidth, ld->config.overheight, ld->config.overformat);
+ ld->overbitmap[1] = auto_bitmap_alloc(ld->config.overwidth, ld->config.overheight, ld->config.overformat);
+ ld->overtex = render_texture_alloc(NULL, NULL);
+ if (ld->overtex == NULL)
+ fatalerror("Out of memory allocating overlay texture");
+ }
+
+ /* register callbacks */
+ config_register(device->machine, "laserdisc", configuration_load, configuration_save);
}
@@ -1650,6 +1978,12 @@ static DEVICE_STOP( laserdisc )
/* make sure all async operations have completed */
if (ld->disc != NULL)
chd_async_complete(ld->disc);
+
+ /* free any textures */
+ if (ld->videotex != NULL)
+ render_texture_free(ld->videotex);
+ if (ld->overtex != NULL)
+ render_texture_free(ld->overtex);
}
@@ -1663,7 +1997,7 @@ static DEVICE_RESET( laserdisc )
int i;
/* attempt to wire up the audio */
- if (sndti_exists(SOUND_CUSTOM, ld->audiocustom))
+ if (ld->audiocustom != -1)
{
sound_token *token = custom_get_token(ld->audiocustom);
token->ld = ld;
@@ -1692,7 +2026,7 @@ static DEVICE_RESET( laserdisc )
ld->statechanged = NULL;
/* each player can init */
- switch (ld->type)
+ switch (ld->config.type)
{
case LASERDISC_TYPE_PIONEER_PR7820:
pr7820_init(ld);
@@ -1702,6 +2036,10 @@ static DEVICE_RESET( laserdisc )
pr8210_init(ld);
break;
+ case LASERDISC_TYPE_SIMUTREK_SPECIAL:
+ simutrek_init(ld);
+ break;
+
case LASERDISC_TYPE_PIONEER_LDV1000:
ldv1000_init(ld);
break;
@@ -1735,9 +2073,9 @@ static DEVICE_SET_INFO( laserdisc )
{
/* --- the following bits of info are set as 64-bit signed integers --- */
case LDINFO_INT_TYPE:
- if (ld != NULL && ld->type != info->i)
+ if (ld != NULL && ld->config.type != info->i)
{
- ld->type = info->i;
+ ld->config.type = info->i;
device_reset(device);
}
break;
@@ -1751,7 +2089,14 @@ static DEVICE_SET_INFO( laserdisc )
DEVICE_GET_INFO( laserdisc )
{
- const laserdisc_config *config = (device != NULL) ? device->inline_config : NULL;
+ const laserdisc_config *config = NULL;
+
+ if (device != NULL)
+ {
+ laserdisc_state *ld = device->token;
+ config = (ld == NULL) ? device->inline_config : &ld->config;
+ }
+
switch (state)
{
/* --- the following bits of info are returned as 64-bit signed integers --- */
@@ -1773,6 +2118,7 @@ DEVICE_GET_INFO( laserdisc )
default:
case LASERDISC_TYPE_PIONEER_PR7820: info->s = "Pioneer PR-7820"; break;
case LASERDISC_TYPE_PIONEER_PR8210: info->s = "Pioneer PR-8210"; break;
+ case LASERDISC_TYPE_SIMUTREK_SPECIAL: info->s = "Simutrek Modified LDP"; break;
case LASERDISC_TYPE_PIONEER_LDV1000: info->s = "Pioneer LD-V1000"; break;
case LASERDISC_TYPE_PHILLIPS_22VP932: info->s = "Philips 22VP932"; break;
case LASERDISC_TYPE_SONY_LDP1450: info->s = "Sony LDP-1450"; break;
@@ -2448,6 +2794,182 @@ static void pr8210_control_w(laserdisc_state *ld, UINT8 data)
/***************************************************************************
+ SIMUTREK MODIFIED PR-8210 PLAYER IMPLEMENTATION
+***************************************************************************/
+
+/*-------------------------------------------------
+
+ Command Set:
+
+ FX XX XX : Seek to frame XXXXX
+ 01-19 : Skip forward 1-19 frames
+ 99-81 : Skip back 1-19 frames
+ 5a : Toggle frame display
+
+-------------------------------------------------*/
+
+/*-------------------------------------------------
+ simutrek_init - Simutrek-specific
+ initialization
+-------------------------------------------------*/
+
+static void simutrek_init(laserdisc_state *ld)
+{
+ /* set up the read callbacks */
+ ld->readline[LASERDISC_LINE_STATUS] = simutrek_status_r;
+
+ /* set up the write callbacks */
+ ld->writedata = simutrek_data_w;
+
+ /* do a soft reset */
+ simutrek_soft_reset(ld);
+}
+
+
+/*-------------------------------------------------
+ simutrek_soft_reset - Simutrek-specific
+ soft reset
+-------------------------------------------------*/
+
+static void simutrek_soft_reset(laserdisc_state *ld)
+{
+ simutrek_info *simutrek = &ld->u.simutrek;
+
+ ld->audio = AUDIO_CH1_ENABLE | AUDIO_CH2_ENABLE;
+ ld->display = 0;
+ simutrek->firstbittime = simutrek->lastbittime = timer_get_time();
+ simutrek->accumulator = 0;
+ simutrek->lastcommand = 0;
+ simutrek->seekstate = 0;
+ simutrek->cmdcnt = 0;
+ simutrek->cmdbytes[0] = 0;
+ simutrek->cmdbytes[1] = 0;
+ simutrek->cmdbytes[2] = 0;
+}
+
+
+/*-------------------------------------------------
+ simutrek_status_r - Simutrek-specific
+ command processing
+-------------------------------------------------*/
+
+static UINT8 simutrek_status_r(laserdisc_state *ld)
+{
+ return (ld->state != LASERDISC_SEARCHING_FRAME) ? ASSERT_LINE : CLEAR_LINE;
+}
+
+
+/*-------------------------------------------------
+ simutrek_data_w - Simutrek-specific
+ data processing
+-------------------------------------------------*/
+
+static void simutrek_data_w(laserdisc_state *ld, UINT8 prev, UINT8 data)
+{
+ simutrek_info *simutrek = &ld->u.simutrek;
+
+ /* Acknowledge every command byte */
+ if (simutrek->cmd_ack_callback != NULL)
+ (*simutrek->cmd_ack_callback)();
+
+ /* Is this byte part of a multi-byte seek command? */
+ if (simutrek->cmdcnt > 0)
+ {
+ CMDPRINTF(("Simutrek: Seek to frame byte %d of 3\n", simutrek->cmdcnt + 1));
+ simutrek->cmdbytes[simutrek->cmdcnt++] = data;
+
+ if (simutrek->cmdcnt == 3)
+ {
+ int frame = ((simutrek->cmdbytes[0] & 0xf) * 10000) +
+ ((simutrek->cmdbytes[1] >> 4) * 1000) +
+ ((simutrek->cmdbytes[1] & 0xf) * 100) +
+ ((simutrek->cmdbytes[2] >> 4) * 10) +
+ (simutrek->cmdbytes[2] & 0xf);
+
+ CMDPRINTF(("Simutrek: Seek to frame %d\n", frame));
+
+ if (laserdisc_ready(ld))
+ set_state(ld, LASERDISC_SEARCHING_FRAME, SIMUTREK_SEARCH_SPEED, frame);
+
+ simutrek->cmdcnt = 0;
+ }
+ }
+ else if (data == 0)
+ {
+ CMDPRINTF(("Simutrek: 0 ?\n"));
+ }
+ else if ((data & 0xf0) == 0xf0)
+ {
+ CMDPRINTF(("Simutrek: Seek to frame byte 1 of 3\n"));
+ simutrek->cmdbytes[simutrek->cmdcnt++] = data;
+ }
+ else if ((data >= 1) && (data <= 0x19))
+ {
+ int step = ((data >> 4) * 10) + (data & 0xf);
+ CMDPRINTF(("Simutrek: Step forwards by %d frame(s)\n", step));
+
+ if (laserdisc_ready(ld))
+ {
+ set_state(ld, LASERDISC_STEPPING_FORWARD, STOP_SPEED, NULL_TARGET_FRAME);
+ add_to_current_track(ld, step * ONE_TRACK);
+ }
+ }
+ else if ((data >= 0x81) && (data <= 0x99))
+ {
+ int step = 100 - (((data >> 4) * 10) + (data & 0xf));
+ CMDPRINTF(("Simutrek: Step backwards by %d frame(s)\n", step));
+
+ if (laserdisc_ready(ld))
+ {
+ set_state(ld, LASERDISC_STEPPING_REVERSE, STOP_SPEED, NULL_TARGET_FRAME);
+ add_to_current_track(ld, step * -ONE_TRACK);
+ }
+ }
+ else if (data == 0x5a)
+ {
+ CMDPRINTF(("Simutrek: Frame window toggle\n"));
+ ld->display ^= 1;
+ }
+ else
+ {
+ CMDPRINTF(("Simutrek: Unknown command (%.2x)\n", data));
+ }
+}
+
+
+/*-------------------------------------------------
+ simutrek_set_audio_squelch - Simutrek-specific
+ command to enable/disable audio squelch
+-------------------------------------------------*/
+
+void simutrek_set_audio_squelch(const device_config *device, int state)
+{
+ laserdisc_state *ld = get_safe_token(device);
+
+ if (state == ASSERT_LINE)
+ ld->audio |= AUDIO_SQUELCH_OVERRIDE;
+ else
+ ld->audio &= ~AUDIO_SQUELCH_OVERRIDE;
+}
+
+
+/*-------------------------------------------------
+ simutrek_set_audio_squelch - Simutrek-specific
+ command to set callback function for
+ player/interface command acknowledge
+-------------------------------------------------*/
+
+void simutrek_set_cmd_ack_callback(const device_config *device, void (*callback)(void))
+{
+ laserdisc_state *ld = get_safe_token(device);
+ simutrek_info *simutrek = &ld->u.simutrek;
+
+ simutrek->cmd_ack_callback = callback;
+}
+
+
+
+/***************************************************************************
PIONEER LD-V1000 IMPLEMENTATION
***************************************************************************/
diff --git a/src/emu/machine/laserdsc.h b/src/emu/machine/laserdsc.h
index 04b22f7451b..653f2fbc0b8 100644
--- a/src/emu/machine/laserdsc.h
+++ b/src/emu/machine/laserdsc.h
@@ -27,6 +27,7 @@ enum
{
LASERDISC_TYPE_PIONEER_PR7820, /* Pioneer PR-7820 */
LASERDISC_TYPE_PIONEER_PR8210, /* Pioneer PR-8210 / LD-V1100 */
+ LASERDISC_TYPE_SIMUTREK_SPECIAL, /* Pioneer PR-8210 with mods */
LASERDISC_TYPE_PIONEER_LDV1000, /* Pioneer LD-V1000 */
LASERDISC_TYPE_PHILLIPS_22VP932, /* Phillips 22VP932 (PAL) */
LASERDISC_TYPE_SONY_LDP1450 /* Sony LDP-1450 */
@@ -68,8 +69,18 @@ typedef void (*laserdisc_audio_func)(const device_config *device, int samplerate
typedef struct _laserdisc_config laserdisc_config;
struct _laserdisc_config
{
- int type;
+ UINT32 type;
laserdisc_audio_func audio;
+
+ /* rendering information */
+ const char * screen;
+
+ /* overlay information */
+ video_update_func overupdate;
+ UINT32 overwidth, overheight, overformat;
+ rectangle overclip;
+ float overposx, overposy;
+ float overscalex, overscaley;
};
@@ -85,10 +96,52 @@ struct _laserdisc_config
#define MDRV_LASERDISC_AUDIO(_func) \
MDRV_DEVICE_CONFIG_DATAPTR(laserdisc_config, audio, _func)
+#define MDRV_LASERDISC_SCREEN(_tag) \
+ MDRV_DEVICE_CONFIG_DATAPTR(laserdisc_config, screen, _tag)
+
+#define MDRV_LASERDISC_OVERLAY(_update, _width, _height, _format) \
+ MDRV_DEVICE_CONFIG_DATAPTR(laserdisc_config, overupdate, video_update_##_update) \
+ MDRV_DEVICE_CONFIG_DATA32(laserdisc_config, overwidth, _width) \
+ MDRV_DEVICE_CONFIG_DATA32(laserdisc_config, overheight, _height) \
+ MDRV_DEVICE_CONFIG_DATA32(laserdisc_config, overformat, _format)
+
+#define MDRV_LASERDISC_OVERLAY_CLIP(_minx, _maxx, _miny, _maxy) \
+ MDRV_DEVICE_CONFIG_DATA32(laserdisc_config, overclip.min_x, _minx) \
+ MDRV_DEVICE_CONFIG_DATA32(laserdisc_config, overclip.max_x, _maxx) \
+ MDRV_DEVICE_CONFIG_DATA32(laserdisc_config, overclip.min_y, _miny) \
+ MDRV_DEVICE_CONFIG_DATA32(laserdisc_config, overclip.max_y, _maxy)
+
+#define MDRV_LASERDISC_OVERLAY_POSITION(_posx, _posy) \
+ MDRV_DEVICE_CONFIG_DATAFP32(laserdisc_config, overposx, _posx, 24) \
+ MDRV_DEVICE_CONFIG_DATAFP32(laserdisc_config, overposy, _posy, 24)
+
+#define MDRV_LASERDISC_OVERLAY_SCALE(_scalex, _scaley) \
+ MDRV_DEVICE_CONFIG_DATAFP32(laserdisc_config, overscalex, _scalex, 24) \
+ MDRV_DEVICE_CONFIG_DATAFP32(laserdisc_config, overscaley, _scaley, 24)
+
#define MDRV_LASERDISC_REMOVE(_tag, _type) \
MDRV_DEVICE_REMOVE(_tag, _type)
+/* use these to add laserdisc screens with proper video update parameters */
+#define MDRV_LASERDISC_SCREEN_ADD_NTSC(_tag, _overlayformat) \
+ MDRV_VIDEO_ATTRIBUTES(VIDEO_SELF_RENDER) \
+ MDRV_VIDEO_UPDATE(laserdisc) \
+ \
+ MDRV_SCREEN_ADD(_tag, RASTER) \
+ MDRV_SCREEN_FORMAT(_overlayformat) \
+ MDRV_SCREEN_RAW_PARAMS(XTAL_14_31818MHz*2, 910, 0, 704, 525, 0, 480) \
+
+/* not correct yet; fix me... */
+#define MDRV_LASERDISC_SCREEN_ADD_PAL(_tag, _format) \
+ MDRV_VIDEO_ATTRIBUTES(VIDEO_SELF_RENDER) \
+ MDRV_VIDEO_UPDATE(laserdisc) \
+ \
+ MDRV_SCREEN_ADD(_tag, RASTER) \
+ MDRV_SCREEN_FORMAT(_format) \
+ MDRV_SCREEN_RAW_PARAMS(XTAL_14_31818MHz, 910, 0, 704, 525.0/2, 0, 480/2) \
+
+
/***************************************************************************
GLOBAL VARIABLES
@@ -140,6 +193,35 @@ UINT8 laserdisc_line_r(const device_config *device, UINT8 line);
/* specify the "slow" speed of the Pioneer PR-7820 */
void pr7820_set_slow_speed(const device_config *device, double frame_rate_scaler);
+/* control the audio squelch of the Simutrek modified players */
+void simutrek_set_audio_squelch(const device_config *device, int state);
+
+/* set the callback */
+void simutrek_set_cmd_ack_callback(const device_config *device, void (*callback)(void));
+
+
+
+/* ----- video interface ----- */
+
+/* enable/disable the video */
+void laserdisc_video_enable(const device_config *device, int enable);
+
+/* enable/disable the overlay */
+void laserdisc_overlay_enable(const device_config *device, int enable);
+
+/* video update callback */
+VIDEO_UPDATE( laserdisc );
+
+
+
+/* ----- configuration ----- */
+
+/* return a copy of the current live configuration settings */
+void laserdisc_get_config(const device_config *device, laserdisc_config *config);
+
+/* change the current live configuration settings */
+void laserdisc_set_config(const device_config *device, const laserdisc_config *config);
+
/* ----- device interface ----- */
@@ -148,4 +230,5 @@ void pr7820_set_slow_speed(const device_config *device, double frame_rate_scaler
#define LASERDISC DEVICE_GET_INFO_NAME(laserdisc)
DEVICE_GET_INFO( laserdisc );
+
#endif /* __LASERDSC_H__ */
diff --git a/src/emu/rendersw.c b/src/emu/rendersw.c
index 5e536a1b2c7..bf98bcaf19e 100644
--- a/src/emu/rendersw.c
+++ b/src/emu/rendersw.c
@@ -210,6 +210,50 @@ INLINE UINT32 get_texel_palette16_bilinear(const render_texinfo *texture, INT32
/*-------------------------------------------------
+ get_texel_palette16a_nearest - return the
+ nearest neighbor texel from a palettized
+ 16bpp source
+-------------------------------------------------*/
+
+INLINE UINT32 get_texel_palette16a_nearest(const render_texinfo *texture, INT32 curu, INT32 curv)
+{
+ const UINT16 *texbase = (const UINT16 *)texture->base + (curv >> 16) * texture->rowpixels + (curu >> 16);
+ return texture->palette[texbase[0]];
+}
+
+
+/*-------------------------------------------------
+ get_texel_palette16a_bilinear - return a
+ bilinear filtered texel from a palettized
+ 16bpp source
+-------------------------------------------------*/
+
+INLINE UINT32 get_texel_palette16a_bilinear(const render_texinfo *texture, INT32 curu, INT32 curv)
+{
+ const UINT16 *texbase = texture->base;
+ rgb_t pix00, pix01, pix10, pix11;
+ INT32 u0, u1, v0, v1;
+
+ u0 = curu >> 16;
+ u1 = 1;
+ if (u0 < 0) u0 = u1 = 0;
+ else if (u0 + 1 >= texture->width) u0 = texture->width - 1, u1 = 0;
+ v0 = curv >> 16;
+ v1 = texture->rowpixels;
+ if (v0 < 0) v0 = v1 = 0;
+ else if (v0 + 1 >= texture->height) v0 = texture->height - 1, v1 = 0;
+
+ texbase += v0 * texture->rowpixels + u0;
+
+ pix00 = texture->palette[texbase[0]];
+ pix01 = texture->palette[texbase[u1]];
+ pix10 = texture->palette[texbase[v1]];
+ pix11 = texture->palette[texbase[u1 + v1]];
+ return rgba_bilinear_filter(pix00, pix01, pix10, pix11, curu >> 8, curv >> 8);
+}
+
+
+/*-------------------------------------------------
get_texel_rgb15_nearest - return the
nearest neighbor texel from a 15bpp RGB source
-------------------------------------------------*/
@@ -1004,7 +1048,7 @@ static void FUNC_PREFIX(draw_quad_palettea16_alpha)(const render_primitive *prim
/* loop over cols */
for (x = setup->startx; x < endx; x++)
{
- UINT32 pix = GET_TEXEL(palette16)(&prim->texture, curu, curv);
+ UINT32 pix = GET_TEXEL(palette16a)(&prim->texture, curu, curv);
UINT32 ta = pix >> 24;
if (ta != 0)
{
@@ -1047,7 +1091,7 @@ static void FUNC_PREFIX(draw_quad_palettea16_alpha)(const render_primitive *prim
/* loop over cols */
for (x = setup->startx; x < endx; x++)
{
- UINT32 pix = GET_TEXEL(palette16)(&prim->texture, curu, curv);
+ UINT32 pix = GET_TEXEL(palette16a)(&prim->texture, curu, curv);
UINT32 ta = (pix >> 24) * sa;
if (ta != 0)
{
diff --git a/src/emu/romload.c b/src/emu/romload.c
index 54e4fe5f907..58d215602bd 100644
--- a/src/emu/romload.c
+++ b/src/emu/romload.c
@@ -1010,7 +1010,7 @@ static void process_disk_entries(rom_load_data *romdata, const char *regiontag,
sprintf(&romdata->errorbuf[strlen(romdata->errorbuf)], "%s NOT FOUND\n", astring_c(filename));
/* if this is NO_DUMP, keep going, though the system may not be able to handle it */
- if (hash_data_has_info(ROM_GETHASHDATA(romp), HASH_INFO_NO_DUMP))
+ if (hash_data_has_info(ROM_GETHASHDATA(romp), HASH_INFO_NO_DUMP) || DISK_ISOPTIONAL(romp))
romdata->warnings++;
else
romdata->errors++;
diff --git a/src/emu/romload.h b/src/emu/romload.h
index 496284053b7..1df8eea801f 100644
--- a/src/emu/romload.h
+++ b/src/emu/romload.h
@@ -208,6 +208,7 @@ struct _rom_load_data
/* ----- per-disk macros ----- */
#define DISK_GETINDEX(r) ((r)->_offset)
#define DISK_ISREADONLY(r) ((ROM_GETFLAGS(r) & DISK_READONLYMASK) == DISK_READONLY)
+#define DISK_ISOPTIONAL(r) ((ROM_GETFLAGS(r) & ROM_OPTIONALMASK) == ROM_OPTIONAL)
/* ----- start/stop macros ----- */
@@ -259,6 +260,7 @@ struct _rom_load_data
#define DISK_REGION(tag) ROM_REGION(1, tag, ROMREGION_DATATYPEDISK)
#define DISK_IMAGE(name,idx,hash) ROMX_LOAD(name, idx, 0, hash, DISK_READWRITE)
#define DISK_IMAGE_READONLY(name,idx,hash) ROMX_LOAD(name, idx, 0, hash, DISK_READONLY)
+#define DISK_IMAGE_READONLY_OPTIONAL(name,idx,hash) ROMX_LOAD(name, idx, 0, hash, DISK_READONLY | ROM_OPTIONAL)
/* ----- hash macros ----- */
diff --git a/src/emu/ui.c b/src/emu/ui.c
index 975c7818426..f14064396fb 100644
--- a/src/emu/ui.c
+++ b/src/emu/ui.c
@@ -12,6 +12,7 @@
#include "driver.h"
#include "osdepend.h"
#include "video/vector.h"
+#include "machine/laserdsc.h"
#include "profiler.h"
#include "cheat.h"
#include "render.h"
@@ -151,9 +152,14 @@ static INT32 slider_xscale(running_machine *machine, INT32 newval, char *buffer,
static INT32 slider_yscale(running_machine *machine, INT32 newval, char *buffer, void *arg);
static INT32 slider_xoffset(running_machine *machine, INT32 newval, char *buffer, void *arg);
static INT32 slider_yoffset(running_machine *machine, INT32 newval, char *buffer, void *arg);
+static INT32 slider_overxscale(running_machine *machine, INT32 newval, char *buffer, void *arg);
+static INT32 slider_overyscale(running_machine *machine, INT32 newval, char *buffer, void *arg);
+static INT32 slider_overxoffset(running_machine *machine, INT32 newval, char *buffer, void *arg);
+static INT32 slider_overyoffset(running_machine *machine, INT32 newval, char *buffer, void *arg);
static INT32 slider_flicker(running_machine *machine, INT32 newval, char *buffer, void *arg);
static INT32 slider_beam(running_machine *machine, INT32 newval, char *buffer, void *arg);
static char *slider_get_screen_desc(const device_config *screen);
+static char *slider_get_laserdisc_desc(const device_config *screen);
#ifdef MAME_DEBUG
static INT32 slider_crossscale(running_machine *machine, INT32 newval, char *buffer, void *arg);
static INT32 slider_crossoffset(running_machine *machine, INT32 newval, char *buffer, void *arg);
@@ -1530,9 +1536,8 @@ static UINT32 handler_load_save(running_machine *machine, UINT32 state)
static void slider_init(running_machine *machine)
{
- int numscreens = video_screen_count(machine->config);
- const input_port_config *port;
const input_field_config *field;
+ const input_port_config *port;
const device_config *device;
int numitems, item;
@@ -1571,15 +1576,14 @@ static void slider_init(running_machine *machine)
slider_config(&slider_list[slider_count++], 10, 1000, 2000, 1, slider_overclock, (void *)(FPTR)item);
}
- for (item = 0; item < numscreens; item++)
+ for (device = video_screen_first(machine->config); device != NULL; device = video_screen_next(device))
{
- const device_config *screen = device_list_find_by_index(machine->config->devicelist, VIDEO_SCREEN, item);
- const screen_config *scrconfig = screen->inline_config;
+ const screen_config *scrconfig = device->inline_config;
int defxscale = floor(scrconfig->xscale * 1000.0f + 0.5f);
int defyscale = floor(scrconfig->yscale * 1000.0f + 0.5f);
int defxoffset = floor(scrconfig->xoffset * 1000.0f + 0.5f);
int defyoffset = floor(scrconfig->yoffset * 1000.0f + 0.5f);
- void *param = (void *)screen;
+ void *param = (void *)device;
/* add refresh rate tweaker */
if (options_get_bool(mame_options(), OPTION_CHEAT))
@@ -1597,6 +1601,25 @@ static void slider_init(running_machine *machine)
slider_config(&slider_list[slider_count++], -500, defyoffset, 500, 2, slider_yoffset, param);
}
+ for (device = device_list_first(machine->config->devicelist, LASERDISC); device != NULL; device = device_list_next(device, LASERDISC))
+ {
+ const laserdisc_config *config = device->inline_config;
+ if (config->overupdate != NULL)
+ {
+ int defxscale = floor(config->overscalex * 1000.0f + 0.5f);
+ int defyscale = floor(config->overscaley * 1000.0f + 0.5f);
+ int defxoffset = floor(config->overposx * 1000.0f + 0.5f);
+ int defyoffset = floor(config->overposy * 1000.0f + 0.5f);
+ void *param = (void *)device;
+
+ /* add scale and offset controls per-overlay */
+ slider_config(&slider_list[slider_count++], 500, (defxscale == 0) ? 1000 : defxscale, 1500, 2, slider_overxscale, param);
+ slider_config(&slider_list[slider_count++], -500, defxoffset, 500, 2, slider_overxoffset, param);
+ slider_config(&slider_list[slider_count++], 500, (defyscale == 0) ? 1000 : defyscale, 1500, 2, slider_overyscale, param);
+ slider_config(&slider_list[slider_count++], -500, defyoffset, 500, 2, slider_overyoffset, param);
+ }
+ }
+
for (device = video_screen_first(machine->config); device != NULL; device = video_screen_next(device))
{
const screen_config *scrconfig = device->inline_config;
@@ -1938,6 +1961,90 @@ static INT32 slider_yoffset(running_machine *machine, INT32 newval, char *buffer
/*-------------------------------------------------
+ slider_overxscale - screen horizontal scale slider
+ callback
+-------------------------------------------------*/
+
+static INT32 slider_overxscale(running_machine *machine, INT32 newval, char *buffer, void *arg)
+{
+ const device_config *laserdisc = arg;
+ laserdisc_config settings;
+
+ laserdisc_get_config(laserdisc, &settings);
+ if (buffer != NULL)
+ {
+ settings.overscalex = (float)newval * 0.001f;
+ laserdisc_set_config(laserdisc, &settings);
+ sprintf(buffer, "%s %s %.3f", slider_get_laserdisc_desc(laserdisc), "Overlay Horiz Stretch", settings.overscalex);
+ }
+ return floor(settings.overscalex * 1000.0f + 0.5f);
+}
+
+
+/*-------------------------------------------------
+ slider_overyscale - screen vertical scale slider
+ callback
+-------------------------------------------------*/
+
+static INT32 slider_overyscale(running_machine *machine, INT32 newval, char *buffer, void *arg)
+{
+ const device_config *laserdisc = arg;
+ laserdisc_config settings;
+
+ laserdisc_get_config(laserdisc, &settings);
+ if (buffer != NULL)
+ {
+ settings.overscaley = (float)newval * 0.001f;
+ laserdisc_set_config(laserdisc, &settings);
+ sprintf(buffer, "%s %s %.3f", slider_get_laserdisc_desc(laserdisc), "Overlay Vert Stretch", settings.overscaley);
+ }
+ return floor(settings.overscaley * 1000.0f + 0.5f);
+}
+
+
+/*-------------------------------------------------
+ slider_overxoffset - screen horizontal position
+ slider callback
+-------------------------------------------------*/
+
+static INT32 slider_overxoffset(running_machine *machine, INT32 newval, char *buffer, void *arg)
+{
+ const device_config *laserdisc = arg;
+ laserdisc_config settings;
+
+ laserdisc_get_config(laserdisc, &settings);
+ if (buffer != NULL)
+ {
+ settings.overposx = (float)newval * 0.001f;
+ laserdisc_set_config(laserdisc, &settings);
+ sprintf(buffer, "%s %s %.3f", slider_get_laserdisc_desc(laserdisc), "Overlay Horiz Position", settings.overposx);
+ }
+ return floor(settings.overposx * 1000.0f + 0.5f);
+}
+
+
+/*-------------------------------------------------
+ slider_overyoffset - screen vertical position
+ slider callback
+-------------------------------------------------*/
+
+static INT32 slider_overyoffset(running_machine *machine, INT32 newval, char *buffer, void *arg)
+{
+ const device_config *laserdisc = arg;
+ laserdisc_config settings;
+
+ laserdisc_get_config(laserdisc, &settings);
+ if (buffer != NULL)
+ {
+ settings.overposy = (float)newval * 0.001f;
+ laserdisc_set_config(laserdisc, &settings);
+ sprintf(buffer, "%s %s %.3f", slider_get_laserdisc_desc(laserdisc), "Overlay Vert Position", settings.overposy);
+ }
+ return floor(settings.overposy * 1000.0f + 0.5f);
+}
+
+
+/*-------------------------------------------------
slider_flicker - vector flicker slider
callback
-------------------------------------------------*/
@@ -1971,7 +2078,7 @@ static INT32 slider_beam(running_machine *machine, INT32 newval, char *buffer, v
/*-------------------------------------------------
slider_get_screen_desc - returns the
- description for a given screen index
+ description for a given screen
-------------------------------------------------*/
static char *slider_get_screen_desc(const device_config *screen)
@@ -1989,6 +2096,25 @@ static char *slider_get_screen_desc(const device_config *screen)
/*-------------------------------------------------
+ slider_get_laserdisc_desc - returns the
+ description for a given laseridsc
+-------------------------------------------------*/
+
+static char *slider_get_laserdisc_desc(const device_config *laserdisc)
+{
+ int ldcount = device_list_items(laserdisc->machine->config->devicelist, LASERDISC);
+ static char descbuf[256];
+
+ if (ldcount > 1)
+ sprintf(descbuf, "Laserdisc '%s'", laserdisc->tag);
+ else
+ strcpy(descbuf, "Laserdisc");
+
+ return descbuf;
+}
+
+
+/*-------------------------------------------------
slider_crossscale - crosshair scale slider
callback
-------------------------------------------------*/
diff --git a/src/ldplayer/ldplayer.c b/src/ldplayer/ldplayer.c
index 8d71e06cfe2..f24d2ee4aca 100644
--- a/src/ldplayer/ldplayer.c
+++ b/src/ldplayer/ldplayer.c
@@ -15,7 +15,6 @@
#include <ctype.h>
-static render_texture *video_texture;
static astring *filename;
static input_port_value last_controls;
@@ -26,40 +25,6 @@ static UINT8 displaying;
/*************************************
*
- * Video update
- *
- *************************************/
-
-static VIDEO_START( ldplayer )
-{
- /* allocate a video texture */
- video_texture = render_texture_alloc(NULL, NULL);
- if (video_texture == NULL)
- fatalerror("Out of memory allocating video texture");
-}
-
-
-static VIDEO_UPDATE( ldplayer )
-{
- const device_config *laserdisc = device_list_first(screen->machine->config->devicelist, LASERDISC);
- bitmap_t *video_bitmap;
-
- /* now talk to the laserdisc */
- laserdisc_get_video(laserdisc, &video_bitmap);
- if (video_bitmap != NULL)
- render_texture_set_bitmap(video_texture, video_bitmap, NULL, 0, TEXFORMAT_YUY16);
-
- /* add a quad to the screen */
- render_container_empty(render_container_get_screen(screen));
- render_screen_add_quad(screen, 0.0f, 0.0f, 1.0f, 1.0f, MAKE_ARGB(0xff,0xff,0xff,0xff), video_texture, PRIMFLAG_BLENDMODE(BLENDMODE_NONE) | PRIMFLAG_SCREENTEX(1));
-
- return 0;
-}
-
-
-
-/*************************************
- *
* Timers and sync
*
*************************************/
@@ -217,15 +182,6 @@ static MACHINE_DRIVER_START( ldplayer_core )
MDRV_MACHINE_START(ldplayer)
MDRV_MACHINE_RESET(ldplayer)
- /* video hardware */
- MDRV_VIDEO_ATTRIBUTES(VIDEO_SELF_RENDER)
-
- MDRV_SCREEN_ADD("main", RASTER)
- MDRV_SCREEN_FORMAT(BITMAP_FORMAT_RGB32)
-
- MDRV_VIDEO_START(ldplayer)
- MDRV_VIDEO_UPDATE(ldplayer)
-
/* audio hardware */
MDRV_SPEAKER_STANDARD_STEREO("left", "right")
@@ -238,9 +194,7 @@ MACHINE_DRIVER_END
static MACHINE_DRIVER_START( ldplayer_ntsc )
MDRV_IMPORT_FROM(ldplayer_core)
-
- MDRV_SCREEN_MODIFY("main")
- MDRV_SCREEN_RAW_PARAMS(XTAL_14_31818MHz, 910, 0, 720, 525.0/2, 0, 480/2)
+ MDRV_LASERDISC_SCREEN_ADD_NTSC("main", BITMAP_FORMAT_RGB32)
MACHINE_DRIVER_END
diff --git a/src/lib/util/avcomp.c b/src/lib/util/avcomp.c
index 3441bd12670..779150e5be0 100644
--- a/src/lib/util/avcomp.c
+++ b/src/lib/util/avcomp.c
@@ -354,7 +354,7 @@ avcomp_error avcomp_encode_data(avcomp_state *state, const UINT8 *source, UINT8
/* encode the video data */
if (width > 0 && height > 0)
{
- UINT32 vidlength;
+ UINT32 vidlength = 0;
/* encode the video */
err = encode_video(state, width, height, videostart, videostride, videoxor, dest + dstoffs, &vidlength);
@@ -633,7 +633,7 @@ static avcomp_error encode_video_lossless(avcomp_state *state, int width, int he
huffman_error hufferr;
UINT32 outbytes;
UINT8 *output;
-
+
/* set up the output; first byte is 0x80 to indicate lossless encoding */
output = dest;
*output++ = 0x80;
@@ -800,7 +800,7 @@ static avcomp_error decode_video(avcomp_state *state, int width, int height, con
/* if the high bit of the first byte is set, we decode losslessly */
if (source[0] & 0x80)
return decode_video_lossless(state, width, height, source, complength, dest, dstride, dxor);
- else
+ else
return AVCERR_INVALID_DATA;
}
diff --git a/src/mame/drivers/alg.c b/src/mame/drivers/alg.c
index b8e386a9523..b00a472e21f 100644
--- a/src/mame/drivers/alg.c
+++ b/src/mame/drivers/alg.c
@@ -32,11 +32,6 @@ static emu_timer *serial_timer;
static UINT8 serial_timer_active;
static UINT16 input_select;
-static bitmap_t *amiga_bitmap;
-static render_texture *video_texture;
-static render_texture *overlay_texture;
-
-static void video_cleanup(running_machine *machine);
static TIMER_CALLBACK( response_timer );
@@ -72,16 +67,6 @@ static int get_lightgun_pos(const device_config *screen, int player, int *x, int
static VIDEO_START( alg )
{
- /* reset our globals */
- video_texture = NULL;
- overlay_texture = NULL;
-
- /* configure for cleanup */
- add_exit_callback(machine, video_cleanup);
-
- /* allocate Amiga bitmap */
- amiga_bitmap = video_screen_auto_bitmap_alloc(machine->primary_screen);
-
/* standard video start */
VIDEO_START_CALL(amiga);
@@ -91,63 +76,6 @@ static VIDEO_START( alg )
}
-static void video_cleanup(running_machine *machine)
-{
- if (video_texture != NULL)
- render_texture_free(video_texture);
- if (overlay_texture != NULL)
- render_texture_free(overlay_texture);
-}
-
-
-
-/*************************************
- *
- * Video update
- *
- *************************************/
-
-static VIDEO_UPDATE( alg )
-{
- int y;
-
- /* update the Amiga video */
- for (y = cliprect->min_y; y <= cliprect->max_y; y++)
- amiga_render_scanline(screen->machine, amiga_bitmap, y);
-
- /* at the end of the frame, composite the video */
- if (!video_skip_this_frame() && (cliprect->max_y == video_screen_get_visible_area(screen)->max_y))
- {
- bitmap_t *vidbitmap;
- rectangle fixedvis = *video_screen_get_visible_area(screen);
- fixedvis.max_x++;
- fixedvis.max_y++;
-
- /* first lay down the video data */
- laserdisc_get_video(laserdisc, &vidbitmap);
- if (video_texture == NULL)
- video_texture = render_texture_alloc(NULL, NULL);
- render_texture_set_bitmap(video_texture, vidbitmap, NULL, 0, TEXFORMAT_YUY16);
-
- /* then overlay the Amiga video */
- if (overlay_texture == NULL)
- overlay_texture = render_texture_alloc(NULL, NULL);
- render_texture_set_bitmap(overlay_texture, amiga_bitmap, &fixedvis, 0, TEXFORMAT_PALETTEA16);
-
- /* add both quads to the screen */
- render_container_empty(render_container_get_screen(screen));
- render_screen_add_quad(screen, 0.0f, 0.0f, 1.0f, 1.0f, MAKE_ARGB(0xff,0xff,0xff,0xff), video_texture, PRIMFLAG_BLENDMODE(BLENDMODE_NONE) | PRIMFLAG_SCREENTEX(1));
- render_screen_add_quad(screen, 0.0f, 0.0f, 1.0f, 1.0f, MAKE_ARGB(0xff,0xff,0xff,0xff), overlay_texture, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_SCREENTEX(1));
-
- /* display disc information */
- if (laserdisc != NULL)
- popmessage("%s", laserdisc_describe_state(laserdisc));
- }
-
- return 0;
-}
-
-
/*************************************
*
@@ -473,21 +401,19 @@ static MACHINE_DRIVER_START( alg_r1 )
MDRV_NVRAM_HANDLER(generic_0fill)
MDRV_LASERDISC_ADD("laserdisc", SONY_LDP1450)
+ MDRV_LASERDISC_OVERLAY(amiga, 512*2, 262, BITMAP_FORMAT_INDEXED16)
+ MDRV_LASERDISC_OVERLAY_CLIP((129-8)*2, (449+8-1)*2, 44-8, 244+8-1)
/* video hardware */
- MDRV_VIDEO_ATTRIBUTES(VIDEO_SELF_RENDER)
-
- MDRV_SCREEN_ADD("main", RASTER)
- MDRV_SCREEN_REFRESH_RATE(59.97)
- MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0))
- MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16)
+ MDRV_LASERDISC_SCREEN_ADD_NTSC("main", BITMAP_FORMAT_INDEXED16)
+ MDRV_SCREEN_REFRESH_RATE(59.997)
MDRV_SCREEN_SIZE(512*2, 262)
MDRV_SCREEN_VISIBLE_AREA((129-8)*2, (449+8-1)*2, 44-8, 244+8-1)
+
MDRV_PALETTE_LENGTH(4097)
MDRV_PALETTE_INIT(amiga)
MDRV_VIDEO_START(alg)
- MDRV_VIDEO_UPDATE(alg)
/* sound hardware */
MDRV_SPEAKER_STANDARD_STEREO("left", "right")
diff --git a/src/mame/drivers/cliffhgr.c b/src/mame/drivers/cliffhgr.c
index 449e6c6a9f8..5c6bf10adcc 100644
--- a/src/mame/drivers/cliffhgr.c
+++ b/src/mame/drivers/cliffhgr.c
@@ -87,64 +87,10 @@ static const device_config *laserdisc;
static int port_bank = 0;
static int phillips_code = 0;
-static render_texture *video_texture;
-static render_texture *overlay_texture;
-static bitmap_t *last_video_bitmap;
-
static emu_timer *irq_timer;
/********************************************************/
-static void video_cleanup(running_machine *machine)
-{
- if (video_texture != NULL)
- render_texture_free(video_texture);
- if (overlay_texture != NULL)
- render_texture_free(overlay_texture);
-}
-
-static VIDEO_UPDATE( cliff )
-{
- /* update the TMS9928A video */
- VIDEO_UPDATE_CALL(tms9928a);
-
- if (laserdisc != NULL)
- {
- bitmap_t *vidbitmap;
- rectangle fixedvis = *TMS9928A_get_visarea();
- fixedvis.max_x++;
- fixedvis.max_y++;
-
- laserdisc_get_video(laserdisc, &vidbitmap);
-
- /* first lay down the video data */
- if (video_texture == NULL)
- video_texture = render_texture_alloc(NULL, NULL);
- if (vidbitmap != last_video_bitmap)
- render_texture_set_bitmap(video_texture, vidbitmap, NULL, 0, TEXFORMAT_YUY16);
-
- last_video_bitmap = vidbitmap;
-
- /* then overlay the TMS9928A video */
- if (overlay_texture == NULL)
- overlay_texture = render_texture_alloc(NULL, NULL);
- render_texture_set_bitmap(overlay_texture, bitmap, &fixedvis, 0, TEXFORMAT_PALETTEA16);
-
- /* add both quads to the screen */
- render_container_empty(render_container_get_screen(screen));
- render_screen_add_quad(screen, 0.0f, 0.0f, 1.0f, 1.0f, MAKE_ARGB(0xff,0xff,0xff,0xff), video_texture, PRIMFLAG_BLENDMODE(BLENDMODE_NONE) | PRIMFLAG_SCREENTEX(1));
- render_screen_add_quad(screen, 0.0f, 0.0f, 1.0f, 1.0f, MAKE_ARGB(0xff,0xff,0xff,0xff), overlay_texture, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_SCREENTEX(1));
- }
-
- /* display disc information */
- if (laserdisc != NULL)
- popmessage("%s", laserdisc_describe_state(laserdisc));
-
- return 0;
-}
-
-/********************************************************/
-
static WRITE8_HANDLER( cliff_test_led_w )
{
set_led_status( 0, offset ^ 1 );
@@ -746,15 +692,15 @@ static MACHINE_DRIVER_START( cliffhgr )
MDRV_NVRAM_HANDLER(generic_0fill)
MDRV_LASERDISC_ADD("laserdisc", PIONEER_PR8210)
+ MDRV_LASERDISC_OVERLAY(tms9928a, 15+32*8+15, 27+24*8+24, BITMAP_FORMAT_INDEXED16)
+ MDRV_LASERDISC_OVERLAY_CLIP(15-12, 15+32*8+12-1, 27-9, 27+24*8+9-1)
/* start with the TMS9928a video configuration */
MDRV_IMPORT_FROM(tms9928a)
/* override video rendering and raw screen info */
- MDRV_VIDEO_ATTRIBUTES(VIDEO_SELF_RENDER)
- MDRV_VIDEO_UPDATE(cliff)
- MDRV_SCREEN_MODIFY("main")
- MDRV_SCREEN_RAW_PARAMS(13500000, 858, 0, 720, 262.5, 21, 262.5)
+ MDRV_SCREEN_REMOVE("main")
+ MDRV_LASERDISC_SCREEN_ADD_NTSC("main", BITMAP_FORMAT_INDEXED16)
/* sound hardware */
MDRV_SPEAKER_STANDARD_STEREO("left", "right")
@@ -822,13 +768,7 @@ ROM_END
static DRIVER_INIT( cliff )
{
- video_texture = NULL;
- overlay_texture = NULL;
- last_video_bitmap = NULL;
-
TMS9928A_configure(&tms9928a_interface);
-
- add_exit_callback(machine, video_cleanup);
}
diff --git a/src/mame/drivers/cubeqst.c b/src/mame/drivers/cubeqst.c
new file mode 100644
index 00000000000..134fddaf5fb
--- /dev/null
+++ b/src/mame/drivers/cubeqst.c
@@ -0,0 +1,700 @@
+/***************************************************************************
+
+ Simutrek Cube Quest
+
+ driver by Phil Bennett
+
+ TODO:
+ * Emulate D8478 laserdisc interface MCU
+ * Accurate video timings
+ - Derive from PROMs
+ * More accurate line fill circuitry emulation
+ - Use PROMs
+
+ Known bugs:
+ * The graphics tend go screwy when you add the first credit on the
+ 'Cubic History' screen.
+ * The guardians' pincer thingies shouldn't distort when they rotate
+
+****************************************************************************/
+
+#include "driver.h"
+#include "cpu/cubeqcpu/cubeqcpu.h"
+#include "deprecat.h"
+#include "sound/custom.h"
+#include "streams.h"
+#include "machine/laserdsc.h"
+
+
+/*************************************
+ *
+ * Constants
+ *
+ *************************************/
+
+/* TODO */
+#define CUBEQST_HBLANK 320
+#define CUBEQST_VCOUNT 280
+
+#define ALPHA_PEN 8192
+
+enum
+{
+ MAIN_CPU = 0,
+ ROTATE_CPU = 1,
+ LINE_CPU = 2,
+ SOUND_CPU = 3,
+} cpu_indices;
+
+
+/*************************************
+ *
+ * Statics
+ *
+ *************************************/
+
+static UINT16 *palette_ram;
+static UINT8 *depth_buffer;
+static int video_field;
+
+static UINT8 io_latch;
+static UINT8 reset_latch;
+
+static int disk_on;
+static int ldp_command_flag;
+static const device_config *laserdisc;
+
+/*************************************
+ *
+ * Video (move to separate file)
+ *
+ *************************************/
+
+static const rectangle overlay_clip = { 0, 320-1, 0, 256-8 };
+
+/* Get a pen number from a palette RAM entry */
+INLINE int get_output_color(UINT16 a)
+{
+ return ((a & 0xf000) >> 3) | ((a & 0x700) >> 2) | ((a & 0x70) >> 1) | (a & 0x7);
+}
+
+
+static VIDEO_START( cubeqst )
+{
+ video_field = 0;
+ depth_buffer = auto_malloc(512);
+
+ render_container_set_palette_alpha(render_container_get_screen(machine->primary_screen), ALPHA_PEN, 0);
+}
+
+/* TODO: Use resistor values */
+static PALETTE_INIT( cubeqst )
+{
+ int i;
+
+ for (i = 0; i < 8192; ++i)
+ {
+ UINT8 r, g, b, y;
+
+ b = i & 7;
+ g = (i >> 3) & 7;
+ r = (i >> 6) & 7;
+ y = ((i >> 9) & 0xf) * 2;
+
+ palette_set_color_rgb(machine, i, y*r, y*g, y*b);
+ }
+}
+
+/* TODO: This is a simplified version of what actually happens */
+static VIDEO_UPDATE( cubeqst )
+{
+ int y;
+
+ int palentry = palette_ram[255];
+
+ /*
+ * Clear the display with palette RAM entry 0xff
+ * This will be either transparent or an actual colour
+ */
+
+ /* Bit 3 selects LD/#GRAPHICS */
+ if ((palentry & (1 << 3)) && disk_on)
+ fillbitmap(bitmap, ALPHA_PEN, cliprect);
+ else
+ fillbitmap(bitmap, screen->machine->pens[get_output_color(palentry)], cliprect);
+
+ cpuintrf_push_context(LINE_CPU);
+
+ /* TODO: Add 1 for linebuffering? */
+ for (y = cliprect->min_y; y <= cliprect->max_y; ++y)
+ {
+ int i;
+ int num_entries = get_ptr_ram_val(y);
+ UINT32 *stk_ram = get_stack_ram();
+ UINT16 *dest = BITMAP_ADDR16(bitmap, y, 0);
+
+ /* Zap the depth buffer */
+ memset(depth_buffer, 0xff, 512);
+
+ /* Process all the spans on this scanline */
+ for (i = 0; i < num_entries; i += 2)
+ {
+ int color = 0, depth = 0;
+ int h1 = 0, h2 = 0;
+ int x;
+
+ int entry1 = stk_ram[(y << 7) | ((i + 0) & 0x7f)];
+ int entry2 = stk_ram[(y << 7) | ((i + 1) & 0x7f)];
+
+ UINT16 palram;
+ UINT16 pen;
+
+ /* Determine which entry is the start point and which is the stop */
+ if ( entry1 & (1 << 19) )
+ {
+ h1 = (entry2 >> 8) & 0x1ff;
+ depth = entry2 & 0xff;
+
+ h2 = (entry1 >> 8) & 0x1ff;
+ color = entry1 & 0xff;
+ }
+ else if ( entry2 & (1 << 19) )
+ {
+ h1 = (entry1 >> 8) & 0x1ff;
+ depth = entry1 & 0xff;
+
+ h2 = (entry2 >> 8) & 0x1ff;
+ color = entry2 & 0xff;
+ }
+ else
+ {
+ // Shouldn't happen...
+ }
+
+ /* Get the 16-bit palette RAM entry */
+ palram = palette_ram[color];
+
+ if (palram & (1 << 3))
+ /* If transparent, draw using our special alpha pen */
+ pen = ALPHA_PEN;
+ else
+ /* Otherwise map the entry to a MAME pen */
+ pen = screen->machine->pens[get_output_color(palram)];
+
+ /* Draw the span, testing for depth */
+ for (x = h1; x <= h2; ++x)
+ {
+ if (!(depth_buffer[x] < depth))
+ {
+ dest[x] = pen;
+ depth_buffer[x] = depth;
+ }
+ }
+ }
+ }
+
+ cpuintrf_pop_context();
+ return 0;
+}
+
+static READ16_HANDLER( line_r )
+{
+ /* I think this is unusued */
+ return video_screen_get_vpos(machine->primary_screen);
+}
+
+static INTERRUPT_GEN( vblank )
+{
+ int int_level = video_field == 0 ? 5 : 6;
+
+ cpunum_set_input_line(machine, MAIN_CPU, int_level, HOLD_LINE);
+
+ /* Update the laserdisc */
+ laserdisc_vsync(laserdisc);
+ video_field ^= 1;
+}
+
+
+/*************************************
+ *
+ * Laserdisc Interface
+ *
+ *************************************/
+
+static WRITE16_HANDLER( laserdisc_w )
+{
+ ldp_command_flag = 1;
+ laserdisc_data_w(laserdisc, data & 0xff);
+}
+
+/* Called by the player emulation to acknowledge the 68000 command */
+void ldp_ack_callback(void)
+{
+ ldp_command_flag = 0;
+}
+
+/*
+ D0: Command acknowledge
+ D1: Seek status (0 = searching, 1 = ready)
+*/
+static READ16_HANDLER( laserdisc_r )
+{
+ int ldp_seek_status = (laserdisc_line_r(laserdisc, LASERDISC_LINE_STATUS) == ASSERT_LINE) ? 1 : 0;
+
+ return (ldp_seek_status << 1) | ldp_command_flag;
+}
+
+
+/* LDP audio squelch control */
+static WRITE16_HANDLER( ldaud_w )
+{
+ simutrek_set_audio_squelch(laserdisc, data & 1 ? ASSERT_LINE : CLEAR_LINE);
+}
+
+/*
+ Control Register
+ ================
+
+ D0: Disk on
+ D1: H Genlock
+ D3: V Genlock
+
+ Note: Can only be written during VBLANK (as with palette RAM)
+*/
+static WRITE16_HANDLER( control_w )
+{
+ disk_on = data & 1;
+}
+
+
+/*************************************
+ *
+ * General Machine Stuff
+ *
+ *************************************/
+
+static TIMER_CALLBACK( delayed_bank_swap )
+{
+ cpuintrf_push_context(LINE_CPU);
+ cubeqcpu_swap_line_banks();
+
+ /* TODO: This is a little dubious */
+ clear_stack();
+
+ cpuintrf_pop_context();
+}
+
+
+static void swap_linecpu_banks(void)
+{
+ /* Best sync up before we switch banks around */
+ timer_call_after_resynch(NULL, 0, delayed_bank_swap);
+}
+
+
+/*
+ Reset Control
+ =============
+
+ D0: /Display (includes rotate and line processors)
+ D1: /Sound
+ D2: /Disk
+*/
+static WRITE16_HANDLER( reset_w )
+{
+ cpunum_set_input_line(machine, ROTATE_CPU, INPUT_LINE_RESET, data & 1 ? CLEAR_LINE : ASSERT_LINE);
+ cpunum_set_input_line(machine, LINE_CPU, INPUT_LINE_RESET, data & 1 ? CLEAR_LINE : ASSERT_LINE);
+ cpunum_set_input_line(machine, SOUND_CPU, INPUT_LINE_RESET, data & 2 ? CLEAR_LINE : ASSERT_LINE);
+
+ /* Swap stack and pointer RAM banks on rising edge of display reset */
+ if (!BIT(reset_latch, 0) && BIT(data, 0))
+ swap_linecpu_banks();
+
+ if (!BIT(data, 2))
+ device_reset(laserdisc);
+
+ reset_latch = data & 0xff;
+}
+
+
+/*************************************
+ *
+ * I/O
+ *
+ *************************************/
+
+static WRITE16_HANDLER( io_w )
+{
+ /*
+ 0: Spare lamp
+ 1: Spare driver
+ 2: Coin counter
+ 3: Left-front lamp
+ 4: Right-front lamp
+ 5: Righ back lamp
+ 6: Spare lamp
+ 7: LED latch clock
+ */
+
+ /* TODO: On rising edge of Q7, status LED latch is written */
+ if ( !BIT(io_latch, 7) && BIT(data, 7) )
+ {
+ /*
+ 0: Battery failure
+ 1: Bad coin
+ 2: No laser unit
+ */
+ }
+
+ io_latch = data;
+}
+
+static READ16_HANDLER( io_r )
+{
+ UINT16 port_data = input_port_read(machine, "IO");
+
+ /*
+ Certain bits depend on Q7 of the IO latch:
+
+ 5: Cube / Trackball H clock
+ 6: R-Fire / Trackball H data
+ 7: L-Fire / Trackball V clock
+ 10: Spare / Trackball V data
+ */
+
+ if ( !BIT(io_latch, 7) )
+ return port_data;
+ else
+ /* Return zeroes for the trackball signals for now */
+ return port_data & ~0x4e0;
+}
+
+/* Trackball ('CHOP') */
+static READ16_HANDLER( chop_r )
+{
+ return (input_port_read(machine, "TRACK_X") << 8) | input_port_read(machine, "TRACK_Y");
+}
+
+
+/*************************************
+ *
+ * Input definitions
+ *
+ *************************************/
+
+static INPUT_PORTS_START( cubeqst )
+ PORT_START("IO")
+ PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_UNUSED )
+ PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_UNUSED )
+ PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_TILT )
+ PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_COIN1 )
+ PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_COIN2 )
+ PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_NAME( "Cube" )
+ PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME( "Right Fire" )
+ PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME( "Left Fire" )
+ PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_SERVICE )
+ PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_COIN3 ) PORT_NAME( "Free Game" )
+ PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_UNUSED )
+ PORT_BIT( 0xf800, IP_ACTIVE_LOW, IPT_UNUSED )
+
+ PORT_START("TRACK_X")
+ PORT_BIT( 0xff, 0x00, IPT_TRACKBALL_X ) PORT_SENSITIVITY(100) PORT_KEYDELTA(10)
+
+ PORT_START("TRACK_Y")
+ PORT_BIT( 0xff, 0x00, IPT_TRACKBALL_Y ) PORT_SENSITIVITY(100) PORT_KEYDELTA(10)
+INPUT_PORTS_END
+
+
+/*************************************
+ *
+ * CPU memory handlers
+ *
+ *************************************/
+
+static ADDRESS_MAP_START( m68k_program_map, ADDRESS_SPACE_PROGRAM, 16 )
+ AM_RANGE(0x000000, 0x01ffff) AM_ROM
+ AM_RANGE(0x020000, 0x027fff) AM_READWRITE(read_rotram, write_rotram)
+ AM_RANGE(0x028000, 0x028fff) AM_READWRITE(read_sndram, write_sndram)
+ AM_RANGE(0x038000, 0x038001) AM_READWRITE(io_r, io_w)
+ AM_RANGE(0x038002, 0x038003) AM_READWRITE(chop_r, ldaud_w)
+ AM_RANGE(0x038008, 0x038009) AM_READWRITE(line_r, reset_w)
+ AM_RANGE(0x03800e, 0x03800f) AM_READWRITE(laserdisc_r, laserdisc_w)
+ AM_RANGE(0x03c800, 0x03c9ff) AM_RAM AM_BASE(&palette_ram)
+ AM_RANGE(0x03cc00, 0x03cc01) AM_WRITE(control_w)
+ AM_RANGE(0x03e000, 0x03efff) AM_RAM AM_MIRROR(0xfc0000) AM_BASE(&generic_nvram16) AM_SIZE(&generic_nvram_size)
+ AM_RANGE(0x03f000, 0x03ffff) AM_RAM AM_MIRROR(0xfc0000)
+ADDRESS_MAP_END
+
+
+/* For the bit-sliced CPUs */
+static ADDRESS_MAP_START( rotate_map, ADDRESS_SPACE_PROGRAM, 64 )
+ AM_RANGE(0x000, 0x1ff) AM_ROM
+ADDRESS_MAP_END
+
+static ADDRESS_MAP_START( line_sound_map, ADDRESS_SPACE_PROGRAM, 64 )
+ AM_RANGE(0x000, 0x0ff) AM_ROM
+ADDRESS_MAP_END
+
+
+/*************************************
+ *
+ * Initialisation
+ *
+ *************************************/
+
+static MACHINE_START( cubeqst )
+{
+ laserdisc = device_list_find_by_tag(machine->config->devicelist, LASERDISC, "laserdisc");
+ simutrek_set_cmd_ack_callback(laserdisc, ldp_ack_callback);
+}
+
+static MACHINE_RESET( cubeqst )
+{
+ reset_latch = 0;
+
+ /* Do this until we sort out the laserdisc interface properly */
+ ldp_command_flag = 0;
+
+ /* Auxillary CPUs are held in reset */
+ cpunum_set_input_line(machine, SOUND_CPU, INPUT_LINE_RESET, ASSERT_LINE);
+ cpunum_set_input_line(machine, ROTATE_CPU, INPUT_LINE_RESET, ASSERT_LINE);
+ cpunum_set_input_line(machine, LINE_CPU, INPUT_LINE_RESET, ASSERT_LINE);
+}
+
+
+/*************************************
+ *
+ * Sound definitions
+ *
+ *************************************/
+
+static sound_stream *cquest_stream;
+
+/*
+ * The sound CPU outputs to a 12-bit 7521 DAC
+ * The DAC output is multiplexed between
+ * 16 channels (8 per side).
+ */
+
+static struct
+{
+ INT16 sample[2][8];
+} cquest_sound;
+
+/* Called by the sound CPU emulation */
+void sound_dac_w(UINT16 data)
+{
+ int side = data & 1;
+ int chan = (data >> 1) & 7;
+ int value = ((data >> 4) & 0xfff);
+
+ /* Sign extend 12-bit to 16-bit */
+ int finalvalue = (value & 0x7ff) - (value & 0x800);
+ if (cquest_sound.sample[side][chan] != finalvalue)
+ {
+ stream_update(cquest_stream);
+ cquest_sound.sample[side][chan] = finalvalue;
+ }
+}
+
+static void cquest_stream_update(void *param, stream_sample_t **inputs, stream_sample_t **buffer, int length)
+{
+ int side;
+
+ /* Clear the buffers */
+ memset(buffer[0], 0, length * sizeof(*buffer[0]));
+ memset(buffer[1], 0, length * sizeof(*buffer[1]));
+
+ for (side = 0; side < 2; ++side)
+ {
+ int chan;
+ for (chan = 0; chan < 8; ++chan)
+ {
+ int samp;
+ for (samp = 0; samp < length; ++samp)
+ buffer[side][samp] += (cquest_sound.sample[side][chan]) * 4;
+ }
+ }
+}
+
+void *cquest_sh_start(int clock, const custom_sound_interface *config)
+{
+ /* Allocate the stream */
+ cquest_stream = stream_create(0, 2, Machine->sample_rate, NULL, cquest_stream_update);
+
+ return auto_malloc(1);
+}
+
+static const custom_sound_interface custom_interface =
+{
+ cquest_sh_start
+};
+
+
+static const cubeqst_snd_config snd_config =
+{
+ sound_dac_w,
+ "sound_proms"
+};
+
+
+/*************************************
+ *
+ * Machine driver
+ *
+ *************************************/
+
+static MACHINE_DRIVER_START( cubeqst )
+ MDRV_CPU_ADD("main_cpu", M68000, XTAL_16MHz / 2)
+ MDRV_CPU_PROGRAM_MAP(m68k_program_map, 0)
+ MDRV_CPU_VBLANK_INT("main", vblank)
+
+ MDRV_CPU_ADD("rotate_cpu", CQUESTROT, XTAL_10MHz / 2)
+ MDRV_CPU_PROGRAM_MAP(rotate_map, 0)
+
+ MDRV_CPU_ADD("line_cpu", CQUESTLIN, XTAL_10MHz / 2)
+ MDRV_CPU_PROGRAM_MAP(line_sound_map, 0)
+
+ MDRV_CPU_ADD("sound_cpu", CQUESTSND, XTAL_10MHz / 2)
+ MDRV_CPU_PROGRAM_MAP(line_sound_map, 0)
+ MDRV_CPU_CONFIG(snd_config)
+
+#if 0
+ MDRV_CPU_ADD("ldp_cpu", I8048, XTAL_10MHz / 2)
+ MDRV_CPU_PROGRAM_MAP(ldp_mem, 0)
+ MDRV_CPU_IO_MAP(ldp_io, 0)
+#endif
+
+ MDRV_INTERLEAVE(700)
+
+ MDRV_MACHINE_START(cubeqst)
+ MDRV_MACHINE_RESET(cubeqst)
+ MDRV_NVRAM_HANDLER(generic_0fill)
+
+ MDRV_LASERDISC_SCREEN_ADD_NTSC("main", BITMAP_FORMAT_INDEXED16)
+ MDRV_VIDEO_START(cubeqst)
+
+ MDRV_PALETTE_LENGTH(8192 + 1)
+ MDRV_PALETTE_INIT(cubeqst)
+
+ MDRV_LASERDISC_ADD("laserdisc", SIMUTREK_SPECIAL)
+ MDRV_LASERDISC_OVERLAY(cubeqst, CUBEQST_HBLANK, CUBEQST_VCOUNT, BITMAP_FORMAT_INDEXED16)
+ MDRV_LASERDISC_OVERLAY_CLIP(0, 320-1, 0, 256-8)
+ MDRV_LASERDISC_OVERLAY_POSITION(0.002, -0.018)
+
+ MDRV_SPEAKER_STANDARD_STEREO("left", "right")
+
+ MDRV_SOUND_ADD("laserdisc", CUSTOM, 0)
+ MDRV_SOUND_CONFIG(laserdisc_custom_interface)
+ MDRV_SOUND_ROUTE(0, "left", 1.0)
+ MDRV_SOUND_ROUTE(1, "right", 1.0)
+
+ MDRV_SOUND_ADD("cubeqst", CUSTOM, 1)
+ MDRV_SOUND_CONFIG(custom_interface)
+ MDRV_SOUND_ROUTE(1, "left", 1.0)
+ MDRV_SOUND_ROUTE(0, "right", 1.0)
+MACHINE_DRIVER_END
+
+
+/*************************************
+ *
+ * ROM definition(s)
+ *
+ *************************************/
+
+ROM_START( cubeqst )
+ ROM_REGION( 0x200000, "main_cpu", 0 )
+ ROM_LOAD16_BYTE( "eprom_bd_2764.1a", 0x000000, 0x02000, CRC(870a28f5) SHA1(6db2020fa10d03bfaf7bd2892ba7266e744567e9) )
+ ROM_LOAD16_BYTE( "eprom_bd_2764.1b", 0x000001, 0x02000, CRC(0c29b2d2) SHA1(1c67dbfaeb6ae1e6ccd870a815bd51ebc520a34c) )
+ ROM_LOAD16_BYTE( "eprom_bd_2764.2a", 0x004000, 0x02000, CRC(f03a76be) SHA1(794a9e5a4fddc16950836468157ea252a82c0771) )
+ ROM_LOAD16_BYTE( "eprom_bd_2764.2b", 0x004001, 0x02000, CRC(c995b786) SHA1(0370e0be81ceea647ea9e27eac22b6c2354e695b) )
+ ROM_LOAD16_BYTE( "eprom_bd_2764.3a", 0x008000, 0x02000, CRC(dedeabf3) SHA1(d06138336bdbd5ebee44188e92e5721ae63715ad) )
+ ROM_LOAD16_BYTE( "eprom_bd_2764.3b", 0x008001, 0x02000, CRC(7353e970) SHA1(9566335868352d3c652621809b812ede309ebded) )
+ ROM_LOAD16_BYTE( "eprom_bd_2764.4a", 0x00c000, 0x02000, CRC(3f8ae830) SHA1(13411f7bee31ae13a2e139ad576e48130838c472) )
+ ROM_LOAD16_BYTE( "eprom_bd_2764.4b", 0x00c001, 0x02000, CRC(6d4fc7cf) SHA1(8f95e2f9e313413ea6b9bcd1ec5d8c11962584db) )
+ ROM_LOAD16_BYTE( "eprom_bd_2764.5a", 0x010000, 0x02000, CRC(ea1a92d0) SHA1(71a6820c67aad951d05571cd29f52c2cebe78c3c) )
+ ROM_LOAD16_BYTE( "eprom_bd_2764.5b", 0x010001, 0x02000, CRC(d12ed62f) SHA1(3e897ef88f51d6b2010944b50f1b5387801d92ce) )
+ ROM_LOAD16_BYTE( "eprom_bd_2764.6a", 0x014000, 0x02000, CRC(6d31f22b) SHA1(36ecfb1c88be9a100a272564d8ff8df02a501f88) )
+ ROM_LOAD16_BYTE( "eprom_bd_2764.6b", 0x014001, 0x02000, CRC(2110f613) SHA1(e12e3b902e9d755fc55ff67851c905e40482a98f) )
+ ROM_LOAD16_BYTE( "eprom_bd_2764.7a", 0x018000, 0x02000, CRC(8b624074) SHA1(592891b384bdab3f851799e50f51b5f04c880490) )
+ ROM_LOAD16_BYTE( "eprom_bd_2764.7b", 0x018001, 0x02000, CRC(f31f2e81) SHA1(b4ae0726ac849662fb1878094a956aa3a9fe94a2) )
+ ROM_LOAD16_BYTE( "eprom_bd_2764.8a", 0x01c000, 0x02000, CRC(8ac5ab0c) SHA1(0cf6593c53184686d7020acd27e2c26aab29137c) )
+ ROM_LOAD16_BYTE( "eprom_bd_2764.8b", 0x01c001, 0x02000, CRC(39804640) SHA1(0f09cf6ef73a9199318278df15983a0cc01ece0d) )
+
+ ROM_REGION64_BE( 0x1000, "rotate_cpu", 0)
+ ROMX_LOAD( "rotate_video_board_82s131.8h", 0x0, 0x200, CRC(1dd1cc65) SHA1(3c83d48f90ba70e81c0d85fb182527afe1f1f68d), ROM_NIBBLE | ROM_SHIFT_NIBBLE_HI | ROM_SKIP(7))
+ ROMX_LOAD( "rotate_video_board_82s131.9h", 0x0, 0x200, CRC(2bbf0aa1) SHA1(1a4ef24a8dc27ac3b01f176aac9b1c1c194bd67b), ROM_NIBBLE | ROM_SHIFT_NIBBLE_LO | ROM_SKIP(7))
+ ROMX_LOAD( "rotate_video_board_82s131.10f", 0x1, 0x200, CRC(89b234eb) SHA1(23d84873b4a5088130fff960b3caded329ea70b5), ROM_NIBBLE | ROM_SHIFT_NIBBLE_HI | ROM_SKIP(7))
+ ROMX_LOAD( "rotate_video_board_82s131.10h", 0x1, 0x200, CRC(d86561b2) SHA1(ebc5374568d9b598237d98f0fb95b68b36a3ddff), ROM_NIBBLE | ROM_SHIFT_NIBBLE_LO | ROM_SKIP(7))
+ ROMX_LOAD( "rotate_video_board_82s131.7h", 0x2, 0x200, CRC(4e0909e2) SHA1(e97dcbd23e0d9eccc138e62334e016b1b333dec3), ROM_NIBBLE | ROM_SHIFT_NIBBLE_HI | ROM_SKIP(7))
+ ROMX_LOAD( "rotate_video_board_82s131.12k", 0x2, 0x200, CRC(84db792f) SHA1(03858d92f4ad5aae39ad1925738df958cc4dd020), ROM_NIBBLE | ROM_SHIFT_NIBBLE_LO | ROM_SKIP(7))
+ ROMX_LOAD( "rotate_video_board_82s131.12j", 0x3, 0x200, CRC(661350ba) SHA1(f1ccc31c7ce1d71f6128c575d508aa04a4a5e15f), ROM_NIBBLE | ROM_SHIFT_NIBBLE_HI | ROM_SKIP(7))
+ ROMX_LOAD( "rotate_video_board_82s131.12d", 0x3, 0x200, CRC(c60762ec) SHA1(d113eb1ce0db4d10a55057332fb17852b312396c), ROM_NIBBLE | ROM_SHIFT_NIBBLE_LO | ROM_SKIP(7))
+ ROMX_LOAD( "rotate_video_board_82s131.12e", 0x4, 0x200, CRC(605b924c) SHA1(899103f20ccec68e432c4abf11f554b0600f8b3c), ROM_NIBBLE | ROM_SHIFT_NIBBLE_HI | ROM_SKIP(7))
+ ROMX_LOAD( "rotate_video_board_82s131.12c", 0x4, 0x200, CRC(fbb881b7) SHA1(b8c1592cfa082fa7dc4abd5392816ba923760cbf), ROM_NIBBLE | ROM_SHIFT_NIBBLE_LO | ROM_SKIP(7))
+ ROMX_LOAD( "rotate_video_board_82s131.12h", 0x5, 0x200, CRC(6fb1d6f0) SHA1(5a0bf681aedde073f0164264620085e9f40eca9e), ROM_NIBBLE | ROM_SHIFT_NIBBLE_HI | ROM_SKIP(7))
+ ROMX_LOAD( "rotate_video_board_82s131.12f", 0x5, 0x200, CRC(5c00d30e) SHA1(ad7bbcce9eff348f78cb6e0782faa175ca928c11), ROM_NIBBLE | ROM_SHIFT_NIBBLE_LO | ROM_SKIP(7))
+
+ ROM_REGION64_BE( 0x800, "line_cpu", 0)
+ ROMX_LOAD( "line_drawer_82s129_u27.6b", 0x0, 0x100, CRC(a9777c19) SHA1(dcb83cc5fce3ff9760dfdfce078895ef71558f67), ROM_NIBBLE | ROM_SHIFT_NIBBLE_HI | ROM_SKIP(7))
+ ROMX_LOAD( "line_drawer_82s129_u28.3b", 0x0, 0x100, CRC(2248790c) SHA1(8473276bcc154a440745b714a31c89c459fef411), ROM_NIBBLE | ROM_SHIFT_NIBBLE_LO | ROM_SKIP(7))
+ ROMX_LOAD( "line_drawer_82s129_u29.3c", 0x1, 0x100, CRC(6accc743) SHA1(a5263a021c594117c14a3d4fbc207a4043001172), ROM_NIBBLE | ROM_SHIFT_NIBBLE_HI | ROM_SKIP(7))
+ ROMX_LOAD( "line_drawer_82s129_u30.3f", 0x1, 0x100, CRC(ba02ac36) SHA1(89473146f04f60bbed6644603ddc646b3d4e04eb), ROM_NIBBLE | ROM_SHIFT_NIBBLE_LO | ROM_SKIP(7))
+ ROMX_LOAD( "line_drawer_82s129_u31.2j", 0x2, 0x100, CRC(bbf50d89) SHA1(f49d4322123c3d4a7d6f664b7164dfe24ddd6eed), ROM_NIBBLE | ROM_SHIFT_NIBBLE_HI | ROM_SKIP(7))
+ ROMX_LOAD( "line_drawer_82s129_u5.3g", 0x2, 0x100, CRC(fa5c239b) SHA1(bbf526362af263aefea87341538157f4ecad686f), ROM_NIBBLE | ROM_SHIFT_NIBBLE_LO | ROM_SKIP(7))
+ ROMX_LOAD( "line_drawer_82s129_u6.2g", 0x3, 0x100, CRC(59874b50) SHA1(d304b4546c187b8c73aaf8887f0037426e60dd5f), ROM_NIBBLE | ROM_SHIFT_NIBBLE_HI | ROM_SKIP(7))
+ ROMX_LOAD( "line_drawer_82s129_u7.3h", 0x3, 0x100, CRC(886956d6) SHA1(ee150a9f99f3177fcc94be5af3f87433f39b311f), ROM_NIBBLE | ROM_SHIFT_NIBBLE_LO | ROM_SKIP(7))
+ ROMX_LOAD( "line_drawer_82s129_u8.3j", 0x4, 0x100, CRC(8d2b17ad) SHA1(f7408104f75e292539aaec688e220c143f762f67), ROM_NIBBLE | ROM_SHIFT_NIBBLE_HI | ROM_SKIP(7))
+ ROMX_LOAD( "line_drawer_82s129_u9.3k", 0x4, 0x100, CRC(0a678253) SHA1(06d7a8f9556eb156ae03184772e76c84ab8d75ea), ROM_NIBBLE | ROM_SHIFT_NIBBLE_LO | ROM_SKIP(7))
+
+ ROM_REGION64_BE( 0x800, "sound_cpu", 0)
+ ROMX_LOAD( "mother_sounds_82s129.7e", 0x0, 0x100, CRC(cf89ad06) SHA1(2f04ca6d57a8c425f51a288f553841db680f5a7e), ROM_NIBBLE | ROM_SHIFT_NIBBLE_HI | ROM_SKIP(7))
+ ROMX_LOAD( "mother_sounds_82s129.7f", 0x0, 0x100, CRC(5208036d) SHA1(ec29af4c10a098fb25424d1a5187a7bd2ec9fb92), ROM_NIBBLE | ROM_SHIFT_NIBBLE_LO | ROM_SKIP(7))
+ ROMX_LOAD( "mother_sounds_82s129.11f", 0x1, 0x100, CRC(af327360) SHA1(2b45358a39daaf5721b5a94c4fd55bd3d0d90ec3), ROM_NIBBLE | ROM_SHIFT_NIBBLE_HI | ROM_SKIP(7))
+ ROMX_LOAD( "mother_sounds_82s129.11e", 0x1, 0x100, CRC(b50d3e43) SHA1(9f2c071c6940767d20a563f6f2c9224e1896a5bf), ROM_NIBBLE | ROM_SHIFT_NIBBLE_LO | ROM_SKIP(7))
+ ROMX_LOAD( "mother_sounds_82s129.9f", 0x2, 0x100, CRC(cd93e3c9) SHA1(f0c11db65ddf2096f6df424b7747242d9e3155da), ROM_NIBBLE | ROM_SHIFT_NIBBLE_HI | ROM_SKIP(7))
+ ROMX_LOAD( "mother_sounds_82s129.10f", 0x2, 0x100, CRC(0e8b8df7) SHA1(37426ffdaf2d21273ac7e88789206fdafb14bc83), ROM_NIBBLE | ROM_SHIFT_NIBBLE_LO | ROM_SKIP(7))
+ ROMX_LOAD( "mother_sounds_82s129.8f", 0x3, 0x100, CRC(07deae27) SHA1(c6a2d7cbf4ea4120f43ae088a3de90bb7a42d4a4), ROM_NIBBLE | ROM_SHIFT_NIBBLE_HI | ROM_SKIP(7))
+ ROMX_LOAD( "mother_sounds_82s129.10e", 0x3, 0x100, CRC(2aaf765e) SHA1(fafe96834f5323fca71b8ab0c013f45c5c47182d), ROM_NIBBLE | ROM_SHIFT_NIBBLE_LO | ROM_SKIP(7))
+ ROMX_LOAD( "mother_sounds_82s129.9e", 0x4, 0x100, CRC(598687e7) SHA1(c5045ddaab7123ff0a4c8f4c2489f9d70b63fc76), ROM_NIBBLE | ROM_SHIFT_NIBBLE_HI | ROM_SKIP(7))
+ ROMX_LOAD( "mother_sounds_82s129.8e", 0x4, 0x100, CRC(68de17ed) SHA1(efefcb4ccdd012b767c4765304c6022b0c091066), ROM_NIBBLE | ROM_SHIFT_NIBBLE_LO | ROM_SKIP(7))
+
+ ROM_REGION( 0x10000, "ldp_cpu", 0)
+ ROM_LOAD( "laser_player_interface_d8748_a308.bin", 0x0000, 0x0400, CRC(eed3e728) SHA1(1eb3467f1c41553375b2c21952cd593b167f5416) )
+
+ ROM_REGION16_BE( 0x1000, "sound_proms", 0)
+ ROMX_LOAD( "mother_sounds_82s185.17f", 0x0, 0x800, CRC(0f49d40e) SHA1(40340833ab27ccb5b60baf44ad01930f204f5318), ROM_NIBBLE | ROM_SHIFT_NIBBLE_LO | ROM_SKIP(1) )
+ ROMX_LOAD( "mother_sounds_82s185.19f", 0x0, 0x800, CRC(a041ce92) SHA1(9bc92992de22b830e479933c50650c7dc23f5713), ROM_NIBBLE | ROM_SHIFT_NIBBLE_HI | ROM_SKIP(1) )
+ ROMX_LOAD( "mother_sounds_82s185.16f", 0x1, 0x800, CRC(75b1749f) SHA1(71da8224e72fb5250e2097666a47314d0a818ee9), ROM_NIBBLE | ROM_SHIFT_NIBBLE_LO | ROM_SKIP(1) )
+ ROMX_LOAD( "mother_sounds_82s185.18f", 0x1, 0x800, CRC(ae4c78ae) SHA1(76fdb8eab372065882caaa5b93ce9e21efe54da5), ROM_NIBBLE | ROM_SHIFT_NIBBLE_HI | ROM_SKIP(1) )
+
+ ROM_REGION( 0x1000, "video_proms", 0 )
+ /* Horizontal and vertical video timing PROMs */
+ ROM_LOAD( "rotate_video_board_82s129.4h", 0x000, 0x100, CRC(6ed1b8d3) SHA1(c392855e1ff8637e551891aefd6c6a3bbcf273a5) )
+ ROM_LOAD( "rotate_video_board_82s129.5h", 0x100, 0x100, CRC(32d839d4) SHA1(7b82e5c1ea5a351eba60c19560a10e4702ae2c22) )
+
+ /* Four sets of (identical) fill circuit state PROMs */
+ ROM_LOAD( "fill_board_82s129.2p", 0x200, 0x100, CRC(c525b091) SHA1(bd172ed3d15f410d09017207ec68faf1d1cb4512) )
+ ROM_LOAD( "fill_board_82s129.3p", 0x300, 0x100, CRC(7ed6c192) SHA1(b02bbcd0e04d3a6c54bec755df55fe6f97d9513f) )
+ ROM_LOAD( "fill_board_82s129.4p", 0x400, 0x100, CRC(6b572b73) SHA1(4a065cb05c12ce34e5598341e0de0cc571b2d387) )
+ ROM_LOAD( "fill_board_82s129.5p", 0x200, 0x100, CRC(c525b091) SHA1(bd172ed3d15f410d09017207ec68faf1d1cb4512) )
+ ROM_LOAD( "fill_board_82s129.6p", 0x300, 0x100, CRC(7ed6c192) SHA1(b02bbcd0e04d3a6c54bec755df55fe6f97d9513f) )
+ ROM_LOAD( "fill_board_82s129.7p", 0x400, 0x100, CRC(6b572b73) SHA1(4a065cb05c12ce34e5598341e0de0cc571b2d387) )
+ ROM_LOAD( "fill_board_82s129.9p", 0x200, 0x100, CRC(c525b091) SHA1(bd172ed3d15f410d09017207ec68faf1d1cb4512) )
+ ROM_LOAD( "fill_board_82s129.10p", 0x300, 0x100, CRC(7ed6c192) SHA1(b02bbcd0e04d3a6c54bec755df55fe6f97d9513f) )
+ ROM_LOAD( "fill_board_82s129.11p", 0x400, 0x100, CRC(6b572b73) SHA1(4a065cb05c12ce34e5598341e0de0cc571b2d387) )
+ ROM_LOAD( "fill_board_82s129.12p", 0x200, 0x100, CRC(c525b091) SHA1(bd172ed3d15f410d09017207ec68faf1d1cb4512) )
+ ROM_LOAD( "fill_board_82s129.13p", 0x300, 0x100, CRC(7ed6c192) SHA1(b02bbcd0e04d3a6c54bec755df55fe6f97d9513f) )
+ ROM_LOAD( "fill_board_82s129.14p", 0x400, 0x100, CRC(6b572b73) SHA1(4a065cb05c12ce34e5598341e0de0cc571b2d387) )
+
+ DISK_REGION( "laserdisc" )
+ DISK_IMAGE_READONLY_OPTIONAL( "cubeqst", 0, SHA1(833c86f967d700de5d31b06d7ab3d84166cf8a50) MD5(d94893847ddd817b04c81d8b0a40a9e5) )
+ROM_END
+
+/*************************************
+ *
+ * Game driver(s)
+ *
+ *************************************/
+
+GAME( 1983, cubeqst, 0, cubeqst, cubeqst, 0, ROT0, "Simutrek", "Cube Quest", 0 )
diff --git a/src/mame/drivers/dlair.c b/src/mame/drivers/dlair.c
index e185f27403a..35275422e78 100644
--- a/src/mame/drivers/dlair.c
+++ b/src/mame/drivers/dlair.c
@@ -71,12 +71,6 @@ static UINT8 last_misc;
static UINT8 laserdisc_type;
static UINT8 laserdisc_data;
-static render_texture *video_texture;
-static render_texture *overlay_texture;
-static UINT32 last_seqid;
-
-static bitmap_t *overlay_bitmap;
-
static const UINT8 led_map[16] =
{ 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7c,0x07,0x7f,0x67,0x77,0x7c,0x39,0x5e,0x79,0x00 };
@@ -148,30 +142,6 @@ static const struct z80_irq_daisy_chain dleuro_daisy_chain[] =
*
*************************************/
-static void video_cleanup(running_machine *machine)
-{
- /* free our textures */
- if (video_texture != NULL)
- render_texture_free(video_texture);
- if (overlay_texture != NULL)
- render_texture_free(overlay_texture);
-}
-
-
-static VIDEO_START( dlair )
-{
- bitmap_t *vidbitmap;
-
- /* create textures */
- last_seqid = laserdisc_get_video(laserdisc, &vidbitmap);
- video_texture = render_texture_alloc(NULL, NULL);
- render_texture_set_bitmap(video_texture, vidbitmap, NULL, 0, TEXFORMAT_YUY16);
- overlay_bitmap = NULL;
-
- add_exit_callback(machine, video_cleanup);
-}
-
-
static PALETTE_INIT( dleuro )
{
int i;
@@ -184,16 +154,6 @@ static PALETTE_INIT( dleuro )
}
-static VIDEO_START( dleuro )
-{
- VIDEO_START_CALL(dlair);
-
- overlay_bitmap = auto_bitmap_alloc(video_screen_get_width(machine->primary_screen), video_screen_get_height(machine->primary_screen), BITMAP_FORMAT_INDEXED16);
- fillbitmap(overlay_bitmap, 8, NULL);
- overlay_texture = render_texture_alloc(NULL, NULL);
-}
-
-
/*************************************
*
@@ -201,31 +161,8 @@ static VIDEO_START( dleuro )
*
*************************************/
-static VIDEO_UPDATE( dlair )
-{
- bitmap_t *vidbitmap;
- UINT32 seqid;
-
- /* get the current video and update the bitmap if different */
- seqid = laserdisc_get_video(laserdisc, &vidbitmap);
- if (seqid != last_seqid)
- render_texture_set_bitmap(video_texture, vidbitmap, NULL, 0, TEXFORMAT_YUY16);
- last_seqid = seqid;
-
- /* cover the whole screen with a quad */
- render_container_empty(render_container_get_screen(screen));
- render_screen_add_quad(screen, 0.0f, 0.0f, 1.0f, 1.0f, MAKE_ARGB(0xff,0xff,0xff,0xff), video_texture, PRIMFLAG_BLENDMODE(BLENDMODE_NONE) | PRIMFLAG_SCREENTEX(1));
-
- popmessage("%s", laserdisc_describe_state(laserdisc));
-
- return 0;
-}
-
-
static VIDEO_UPDATE( dleuro )
{
- bitmap_t *vidbitmap;
- UINT32 seqid;
int x, y;
/* redraw the overlay */
@@ -233,27 +170,9 @@ static VIDEO_UPDATE( dleuro )
for (x = 0; x < 32; x++)
{
UINT8 *base = &videoram[y * 64 + x * 2 + 1];
- drawgfx(overlay_bitmap, screen->machine->gfx[0], base[0], base[1], 0, 0, 10 * x, 16 * y, cliprect, TRANSPARENCY_NONE, 0);
+ drawgfx(bitmap, screen->machine->gfx[0], base[0], base[1], 0, 0, 10 * x, 16 * y, cliprect, TRANSPARENCY_NONE, 0);
}
- /* update the overlay */
- render_texture_set_bitmap(overlay_texture, overlay_bitmap, video_screen_get_visible_area(screen), 0, TEXFORMAT_PALETTE16);
-
- /* get the current video and update the bitmap if different */
- seqid = laserdisc_get_video(laserdisc, &vidbitmap);
- if (seqid != last_seqid)
- render_texture_set_bitmap(video_texture, vidbitmap, NULL, 0, TEXFORMAT_YUY16);
- last_seqid = seqid;
-
- /* cover the whole screen with a quad */
- render_container_empty(render_container_get_screen(screen));
- if (last_misc & 0x02)
- render_screen_add_quad(screen, 0.0f, 0.0f, 1.0f, 1.0f, MAKE_ARGB(0xff,0xff,0xff,0xff), video_texture, PRIMFLAG_BLENDMODE(BLENDMODE_NONE) | PRIMFLAG_SCREENTEX(1));
- else
- render_screen_add_quad(screen, 0.0f, 0.0f, 1.0f, 1.0f, MAKE_ARGB(0xff,0xff,0xff,0xff), overlay_texture, PRIMFLAG_BLENDMODE(BLENDMODE_NONE) | PRIMFLAG_SCREENTEX(1));
-
- popmessage("%s", laserdisc_describe_state(laserdisc));
-
return 0;
}
@@ -799,14 +718,7 @@ static MACHINE_DRIVER_START( dlair_base )
MDRV_MACHINE_RESET(dlair)
/* video hardware */
- MDRV_VIDEO_ATTRIBUTES(VIDEO_SELF_RENDER)
-
- MDRV_SCREEN_ADD("main", RASTER)
- MDRV_SCREEN_FORMAT(BITMAP_FORMAT_RGB32)
- MDRV_SCREEN_RAW_PARAMS(XTAL_14_31818MHz, 910, 0, 720, 525.0/2, 0, 480/2)
-
- MDRV_VIDEO_START(dlair)
- MDRV_VIDEO_UPDATE(dlair)
+ MDRV_LASERDISC_SCREEN_ADD_NTSC("main", BITMAP_FORMAT_RGB32)
/* sound hardware */
MDRV_SPEAKER_STANDARD_STEREO("left", "right")
@@ -849,21 +761,15 @@ static MACHINE_DRIVER_START( dleuro )
MDRV_MACHINE_RESET(dlair)
MDRV_LASERDISC_ADD("laserdisc", PHILLIPS_22VP932)
+ MDRV_LASERDISC_OVERLAY(dleuro, 256, 256, BITMAP_FORMAT_INDEXED16)
/* video hardware */
- MDRV_SCREEN_ADD("main", RASTER)
- MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16)
- MDRV_SCREEN_REFRESH_RATE(50)
- MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0))
- MDRV_SCREEN_SIZE(32*8, 32*8)
- MDRV_SCREEN_VISIBLE_AREA(0, 199, 0, 239)
+ MDRV_LASERDISC_SCREEN_ADD_PAL("main", BITMAP_FORMAT_INDEXED16)
MDRV_GFXDECODE(dlair)
MDRV_PALETTE_LENGTH(16)
MDRV_PALETTE_INIT(dleuro)
- MDRV_VIDEO_START(dleuro)
- MDRV_VIDEO_UPDATE(dleuro)
/* sound hardware */
MDRV_SPEAKER_STANDARD_STEREO("left", "right")
diff --git a/src/mame/drivers/esh.c b/src/mame/drivers/esh.c
index 44557dd54c7..7d980d2f6a7 100644
--- a/src/mame/drivers/esh.c
+++ b/src/mame/drivers/esh.c
@@ -42,6 +42,8 @@ static VIDEO_UPDATE( esh )
{
int charx, chary;
+ render_container_set_palette_alpha(render_container_get_screen(screen), 0, 0x00);
+
/* clear */
fillbitmap(bitmap, 0, cliprect);
@@ -280,7 +282,8 @@ static MACHINE_START( esh )
/* DRIVER */
static MACHINE_DRIVER_START( esh )
-/* main cpu */
+
+ /* main cpu */
MDRV_CPU_ADD("main", Z80, PCB_CLOCK/6) /* The denominator is a Daphne guess based on PacMan's hardware */
MDRV_CPU_PROGRAM_MAP(z80_0_mem,0)
MDRV_CPU_IO_MAP(z80_0_io,0)
@@ -291,23 +294,17 @@ static MACHINE_DRIVER_START( esh )
MDRV_MACHINE_START(esh)
MDRV_LASERDISC_ADD("laserdisc", PIONEER_LDV1000)
+ MDRV_LASERDISC_OVERLAY(esh, 256, 256, BITMAP_FORMAT_INDEXED16)
-/* video */
-
- MDRV_SCREEN_ADD("main", RASTER)
- MDRV_SCREEN_FORMAT(BITMAP_FORMAT_RGB32)
- MDRV_SCREEN_REFRESH_RATE(60)
- MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0))
- MDRV_SCREEN_SIZE(32*8, 32*8)
- MDRV_SCREEN_VISIBLE_AREA(0*8, 32*8-1, 0*8, 32*8-1)
+ /* video hardware */
+ MDRV_LASERDISC_SCREEN_ADD_NTSC("main", BITMAP_FORMAT_INDEXED16)
MDRV_PALETTE_LENGTH(256)
MDRV_PALETTE_INIT(esh)
MDRV_GFXDECODE(esh)
- MDRV_VIDEO_UPDATE(esh)
-/* sound */
+ /* sound hardware */
MDRV_SPEAKER_STANDARD_STEREO("left", "right")
MDRV_SOUND_ADD("laserdisc", CUSTOM, 0)
@@ -334,6 +331,9 @@ ROM_START( esh )
ROM_LOAD( "rgb.j1", 0x000, 0x200, CRC(1e9f795f) SHA1(61a58694929fa39b2412bc9244e5681d65a0eacb) )
ROM_LOAD( "h.c5", 0x200, 0x100, CRC(abde5e4b) SHA1(9dd3a7fd523b519ac613b9f08ae9cc962992cf5d) ) /* Video timing? */
ROM_LOAD( "v.c6", 0x300, 0x100, CRC(7157ba22) SHA1(07355f30efe46196d216356eda48a59fc622e43f) )
+
+ DISK_REGION( "laserdisc" )
+ DISK_IMAGE_READONLY( "esh", 0, NO_DUMP )
ROM_END
ROM_START( esha )
@@ -353,6 +353,9 @@ ROM_START( esha )
ROM_LOAD( "rgb.j1", 0x000, 0x200, CRC(1e9f795f) SHA1(61a58694929fa39b2412bc9244e5681d65a0eacb) )
ROM_LOAD( "h.c5", 0x200, 0x100, CRC(abde5e4b) SHA1(9dd3a7fd523b519ac613b9f08ae9cc962992cf5d) ) /* Video timing? */
ROM_LOAD( "v.c6", 0x300, 0x100, CRC(7157ba22) SHA1(07355f30efe46196d216356eda48a59fc622e43f) )
+
+ DISK_REGION( "laserdisc" )
+ DISK_IMAGE_READONLY( "esh", 0, NO_DUMP )
ROM_END
ROM_START( eshb )
@@ -372,6 +375,9 @@ ROM_START( eshb )
ROM_LOAD( "rgb.j1", 0x000, 0x200, CRC(1e9f795f) SHA1(61a58694929fa39b2412bc9244e5681d65a0eacb) )
ROM_LOAD( "h.c5", 0x200, 0x100, CRC(abde5e4b) SHA1(9dd3a7fd523b519ac613b9f08ae9cc962992cf5d) ) /* Video timing? */
ROM_LOAD( "v.c6", 0x300, 0x100, CRC(7157ba22) SHA1(07355f30efe46196d216356eda48a59fc622e43f) )
+
+ DISK_REGION( "laserdisc" )
+ DISK_IMAGE_READONLY( "esh", 0, NO_DUMP )
ROM_END
diff --git a/src/mame/drivers/gottlieb.c b/src/mame/drivers/gottlieb.c
index 5f55a236aea..2bc9d40541a 100644
--- a/src/mame/drivers/gottlieb.c
+++ b/src/mame/drivers/gottlieb.c
@@ -1885,13 +1885,11 @@ static MACHINE_DRIVER_START( g2laser )
MDRV_LASERDISC_ADD("laserdisc", PIONEER_PR8210)
MDRV_LASERDISC_AUDIO(laserdisc_audio_process)
-
- MDRV_VIDEO_ATTRIBUTES(VIDEO_SELF_RENDER)
- MDRV_VIDEO_START(gottlieb_laserdisc)
- MDRV_VIDEO_UPDATE(gottlieb_laserdisc)
-
- MDRV_SCREEN_MODIFY("main")
- MDRV_SCREEN_RAW_PARAMS(NTSC_CLOCK, 910, 0, 720, 525.0/2, 0, 480/2)
+ MDRV_LASERDISC_OVERLAY(gottlieb, GOTTLIEB_VIDEO_HCOUNT, GOTTLIEB_VIDEO_VCOUNT, BITMAP_FORMAT_INDEXED16)
+ MDRV_LASERDISC_OVERLAY_CLIP(0, GOTTLIEB_VIDEO_HBLANK-1, 0, GOTTLIEB_VIDEO_VBLANK-8)
+
+ MDRV_SCREEN_REMOVE("main")
+ MDRV_LASERDISC_SCREEN_ADD_NTSC("main", BITMAP_FORMAT_INDEXED16)
MDRV_SOUND_ADD("laserdisc", CUSTOM, 0)
MDRV_SOUND_CONFIG(laserdisc_custom_interface)
diff --git a/src/mame/drivers/gpworld.c b/src/mame/drivers/gpworld.c
index 0dd89913c2c..d86f5b1c81e 100644
--- a/src/mame/drivers/gpworld.c
+++ b/src/mame/drivers/gpworld.c
@@ -203,6 +203,8 @@ static void gpworld_draw_sprites(running_machine *machine, bitmap_t *bitmap, con
static VIDEO_UPDATE( gpworld )
{
+ render_container_set_palette_alpha(render_container_get_screen(screen), 0, 0x00);
+
fillbitmap(bitmap, 0, cliprect);
gpworld_draw_tiles(screen->machine, bitmap, cliprect);
@@ -427,7 +429,8 @@ GFXDECODE_END
/* DRIVER */
static MACHINE_DRIVER_START( gpworld )
-/* main cpu */
+
+ /* main cpu */
MDRV_CPU_ADD("main", Z80, GUESSED_CLOCK)
MDRV_CPU_PROGRAM_MAP(mainmem,0)
MDRV_CPU_IO_MAP(mainport,0)
@@ -436,21 +439,15 @@ static MACHINE_DRIVER_START( gpworld )
MDRV_MACHINE_START(gpworld)
MDRV_LASERDISC_ADD("laserdisc", PIONEER_LDV1000)
+ MDRV_LASERDISC_OVERLAY(gpworld, 512, 256, BITMAP_FORMAT_INDEXED16)
-/* video */
-
- MDRV_SCREEN_ADD("main", RASTER)
- MDRV_SCREEN_FORMAT(BITMAP_FORMAT_RGB32)
- MDRV_SCREEN_REFRESH_RATE(60)
- MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0))
- MDRV_SCREEN_SIZE(64*8, 32*8)
- MDRV_SCREEN_VISIBLE_AREA(0*8, 64*8-1, 0*8, 32*8-1)
+ /* video hardware */
+ MDRV_LASERDISC_SCREEN_ADD_NTSC("main", BITMAP_FORMAT_INDEXED16)
MDRV_GFXDECODE(gpworld)
MDRV_PALETTE_LENGTH(1024)
- MDRV_VIDEO_UPDATE(gpworld)
-/* sound */
+ /* sound hardware */
MDRV_SPEAKER_STANDARD_STEREO("left", "right")
MDRV_SOUND_ADD("laserdisc", CUSTOM, 0)
@@ -490,6 +487,9 @@ ROM_START( gpworld )
ROM_LOAD( "pr6146.ic2", 0x000, 0x020, CRC(d10801a0) SHA1(89e9ac0d9c9eee6efd5455a3416c436ceda8f632) )
ROM_LOAD( "pr6147.ic28", 0x020, 0x100, CRC(b7173df9) SHA1(044beda43cb1793033021a08b3ee3441d5ffe6c3) )
ROM_LOAD( "pr5501.ic14", 0x120, 0x100, CRC(1bdf71d4) SHA1(ac52e948cce6df4abb7543c08e2c6454efd63e79) )
+
+ DISK_REGION( "laserdisc" )
+ DISK_IMAGE_READONLY( "gpworld", 0, NO_DUMP )
ROM_END
diff --git a/src/mame/drivers/istellar.c b/src/mame/drivers/istellar.c
index 36bec9d129a..06c5c2281a0 100644
--- a/src/mame/drivers/istellar.c
+++ b/src/mame/drivers/istellar.c
@@ -44,6 +44,8 @@ static VIDEO_UPDATE( istellar )
{
int charx, chary;
+ render_container_set_palette_alpha(render_container_get_screen(screen), 0, 0x00);
+
/* clear */
fillbitmap(bitmap, 0, cliprect);
@@ -325,18 +327,18 @@ static INTERRUPT_GEN( vblank_callback_istellar )
/* DRIVER */
static MACHINE_DRIVER_START( istellar )
-/* main cpu */
+ /* main cpu */
MDRV_CPU_ADD("main", Z80, GUESSED_CLOCK)
MDRV_CPU_PROGRAM_MAP(z80_0_mem,0)
MDRV_CPU_IO_MAP(z80_0_io,0)
MDRV_CPU_VBLANK_INT("main", vblank_callback_istellar)
-/* sound cpu */
+ /* sound cpu */
MDRV_CPU_ADD("audio", Z80, GUESSED_CLOCK)
MDRV_CPU_PROGRAM_MAP(z80_1_mem,0)
MDRV_CPU_IO_MAP(z80_1_io,0)
-/* ldp comm cpu */
+ /* ldp comm cpu */
MDRV_CPU_ADD("sub", Z80, GUESSED_CLOCK)
MDRV_CPU_PROGRAM_MAP(z80_2_mem,0)
MDRV_CPU_IO_MAP(z80_2_io,0)
@@ -344,23 +346,17 @@ static MACHINE_DRIVER_START( istellar )
MDRV_MACHINE_START(istellar)
MDRV_LASERDISC_ADD("laserdisc", PIONEER_LDV1000)
+ MDRV_LASERDISC_OVERLAY(istellar, 256, 256, BITMAP_FORMAT_INDEXED16)
-/* video */
-
- MDRV_SCREEN_ADD("main", RASTER)
- MDRV_SCREEN_FORMAT(BITMAP_FORMAT_RGB32)
- MDRV_SCREEN_REFRESH_RATE(60)
- MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0))
- MDRV_SCREEN_SIZE(32*8, 32*8)
- MDRV_SCREEN_VISIBLE_AREA(0*8, 32*8-1, 0*8, 32*8-1)
+ /* video hardware */
+ MDRV_LASERDISC_SCREEN_ADD_NTSC("main", BITMAP_FORMAT_INDEXED16)
MDRV_PALETTE_LENGTH(256)
MDRV_PALETTE_INIT(istellar)
MDRV_GFXDECODE(istellar)
- MDRV_VIDEO_UPDATE(istellar)
-/* sound */
+ /* sound hardware */
MDRV_SPEAKER_STANDARD_STEREO("left", "right")
MDRV_SOUND_ADD("laserdisc", CUSTOM, 0)
@@ -399,6 +395,9 @@ ROM_START( istellar )
ROM_LOAD( "red6b.bot", 0x000, 0x100, CRC(5c52f844) SHA1(a8a3d91f3247ad13c805d8d8288b07f3cdaf1189) ) /* At IC location C63? (bottom board) - label ? */
ROM_LOAD( "green6c.bot", 0x100, 0x100, CRC(7d8c845c) SHA1(04ae2ca0cc6679e21346ce34e9e01aa5bf4e2067) ) /* At IC location C62? (bottom board) - label ? */
ROM_LOAD( "blue6d.bot", 0x200, 0x100, CRC(5ebb81f9) SHA1(285d60f2894c524ca80fc68ad7c2dfd9093a67ea) ) /* At IC location C61? (bottom board) - label ? */
+
+ DISK_REGION( "laserdisc" )
+ DISK_IMAGE_READONLY( "istellar", 0, NO_DUMP )
ROM_END
diff --git a/src/mame/drivers/lgp.c b/src/mame/drivers/lgp.c
index b29c806c868..5d238a77d07 100644
--- a/src/mame/drivers/lgp.c
+++ b/src/mame/drivers/lgp.c
@@ -83,6 +83,8 @@ static VIDEO_UPDATE( lgp )
{
int charx, chary;
+ render_container_set_palette_alpha(render_container_get_screen(screen), 0, 0x00);
+
/* clear */
fillbitmap(bitmap, 0, cliprect);
@@ -340,13 +342,13 @@ static MACHINE_START( lgp )
/* DRIVER */
static MACHINE_DRIVER_START( lgp )
-/* main cpu */
+ /* main cpu */
MDRV_CPU_ADD("main", Z80, CPU_PCB_CLOCK)
MDRV_CPU_PROGRAM_MAP(main_program_map,0)
MDRV_CPU_IO_MAP(main_io_map,0)
MDRV_CPU_VBLANK_INT("main", vblank_callback_lgp)
-/* sound cpu */
+ /* sound cpu */
MDRV_CPU_ADD("audio", Z80, SOUND_PCB_CLOCK)
MDRV_CPU_PROGRAM_MAP(sound_program_map,0)
MDRV_CPU_IO_MAP(sound_io_map,0)
@@ -354,23 +356,17 @@ static MACHINE_DRIVER_START( lgp )
MDRV_MACHINE_START(lgp)
MDRV_LASERDISC_ADD("laserdisc", PIONEER_LDV1000)
+ MDRV_LASERDISC_OVERLAY(lgp, 256, 256, BITMAP_FORMAT_INDEXED16)
-/* video */
-
- MDRV_SCREEN_ADD("main", RASTER)
- MDRV_SCREEN_FORMAT(BITMAP_FORMAT_RGB32)
- MDRV_SCREEN_REFRESH_RATE(60)
- MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0))
- MDRV_SCREEN_SIZE(32*8, 32*8)
- MDRV_SCREEN_VISIBLE_AREA(0*8, 32*8-1, 0*8, 32*8-1)
+ /* video hardware */
+ MDRV_LASERDISC_SCREEN_ADD_NTSC("main", BITMAP_FORMAT_INDEXED16)
MDRV_PALETTE_LENGTH(256)
/* MDRV_PALETTE_INIT(lgp) */
MDRV_GFXDECODE(lgp)
- MDRV_VIDEO_UPDATE(lgp)
-/* sound */
+ /* sound hardware */
MDRV_SPEAKER_STANDARD_STEREO("left", "right")
MDRV_SOUND_ADD("laserdisc", CUSTOM, 0)
@@ -459,6 +455,9 @@ ROM_START( lgp )
ROM_LOAD( "a02_38.44", 0x00220, 0x100, CRC(6f37212a) SHA1(32b891dc9b97637620b2f1f9d9d76509c333cb2d) )
ROM_LOAD( "a02_39.109", 0x00320, 0x100, CRC(88363809) SHA1(b22a7bd8ce6b28bf7cfa64c3a08e4cf7f9b4cd20) )
ROM_LOAD( "a02_40.110", 0x00420, 0x100, CRC(fdfc7aac) SHA1(2413f7f9ad11c91d2adc0aab37bf70ff5c68ab6f) )
+
+ DISK_REGION( "laserdisc" )
+ DISK_IMAGE_READONLY( "lgp", 0, NO_DUMP )
ROM_END
diff --git a/src/mame/drivers/segald.c b/src/mame/drivers/segald.c
index b916ca564af..f51ca6523f0 100644
--- a/src/mame/drivers/segald.c
+++ b/src/mame/drivers/segald.c
@@ -80,6 +80,8 @@ static void astron_draw_sprites(bitmap_t *bitmap, const rectangle *cliprect)
static VIDEO_UPDATE( astron )
{
+ render_container_set_palette_alpha(render_container_get_screen(screen), 0, 0x00);
+
fillbitmap(bitmap, 0, cliprect);
astron_draw_characters(screen->machine, bitmap, cliprect);
@@ -341,7 +343,8 @@ static MACHINE_START( astron )
/* DRIVER */
static MACHINE_DRIVER_START( astron )
-/* main cpu */
+
+ /* main cpu */
MDRV_CPU_ADD("main", Z80, SCHEMATIC_CLOCK/4)
MDRV_CPU_PROGRAM_MAP(mainmem,0)
MDRV_CPU_IO_MAP(mainport,0)
@@ -351,19 +354,13 @@ static MACHINE_DRIVER_START( astron )
MDRV_MACHINE_START(astron)
MDRV_LASERDISC_ADD("laserdisc", PIONEER_LDV1000)
+ MDRV_LASERDISC_OVERLAY(astron, 256, 256, BITMAP_FORMAT_INDEXED16)
-/* video */
-
- MDRV_SCREEN_ADD("main", RASTER)
- MDRV_SCREEN_FORMAT(BITMAP_FORMAT_RGB32)
- MDRV_SCREEN_REFRESH_RATE(60)
- MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0))
- MDRV_SCREEN_SIZE(32*8, 32*8)
- MDRV_SCREEN_VISIBLE_AREA(0*8, 32*8-1, 0*8, 32*8-1)
+ /* video hardware */
+ MDRV_LASERDISC_SCREEN_ADD_NTSC("main", BITMAP_FORMAT_INDEXED16)
MDRV_GFXDECODE(segald)
MDRV_PALETTE_LENGTH(256)
- MDRV_VIDEO_UPDATE(astron)
/* sound hardare */
MDRV_SPEAKER_STANDARD_STEREO("left", "right")
@@ -403,6 +400,9 @@ ROM_START( astron )
ROM_LOAD( "pr-5277.bin", 0x100, 0x100, CRC(bf2c33ab) SHA1(4a83b3e9b74b900621e8f42edf94cc04b791cdd0) )
ROM_LOAD( "pr-5276.bin", 0x200, 0x20, CRC(91267e8a) SHA1(ae5bd8efea5322c4d9986d06680a781392f9a642) )
ROM_LOAD( "pr-5275.bin", 0x220, 0x20, CRC(0c872a9b) SHA1(eaabce5d867a4e896bd356abc94429f9a4eec372) )
+
+ DISK_REGION( "laserdisc" )
+ DISK_IMAGE_READONLY( "astron", 0, NO_DUMP )
ROM_END
ROM_START( astronp )
@@ -433,6 +433,9 @@ ROM_START( astronp )
ROM_LOAD( "pr-5277.bin", 0x100, 0x100, CRC(bf2c33ab) SHA1(4a83b3e9b74b900621e8f42edf94cc04b791cdd0) )
ROM_LOAD( "pr-5276.bin", 0x200, 0x20, CRC(91267e8a) SHA1(ae5bd8efea5322c4d9986d06680a781392f9a642) )
ROM_LOAD( "pr-5275.bin", 0x220, 0x20, CRC(0c872a9b) SHA1(eaabce5d867a4e896bd356abc94429f9a4eec372) )
+
+ DISK_REGION( "laserdisc" )
+ DISK_IMAGE_READONLY( "astron", 0, NO_DUMP )
ROM_END
ROM_START( galaxyr )
@@ -465,6 +468,9 @@ ROM_START( galaxyr )
ROM_LOAD( "pr-5277.bin", 0x100, 0x100, CRC(bf2c33ab) SHA1(4a83b3e9b74b900621e8f42edf94cc04b791cdd0) )
ROM_LOAD( "pr-5276.bin", 0x200, 0x20, CRC(91267e8a) SHA1(ae5bd8efea5322c4d9986d06680a781392f9a642) )
ROM_LOAD( "pr-5275.bin", 0x220, 0x20, CRC(0c872a9b) SHA1(eaabce5d867a4e896bd356abc94429f9a4eec372) )
+
+ DISK_REGION( "laserdisc" )
+ DISK_IMAGE_READONLY( "galaxyr", 0, NO_DUMP )
ROM_END
ROM_START( galaxyrp )
@@ -497,6 +503,9 @@ ROM_START( galaxyrp )
ROM_LOAD( "pr-5277.bin", 0x100, 0x100, CRC(bf2c33ab) SHA1(4a83b3e9b74b900621e8f42edf94cc04b791cdd0) )
ROM_LOAD( "pr-5276.bin", 0x200, 0x20, CRC(91267e8a) SHA1(ae5bd8efea5322c4d9986d06680a781392f9a642) )
ROM_LOAD( "pr-5275.bin", 0x220, 0x20, CRC(0c872a9b) SHA1(eaabce5d867a4e896bd356abc94429f9a4eec372) )
+
+ DISK_REGION( "laserdisc" )
+ DISK_IMAGE_READONLY( "galaxyr", 0, NO_DUMP )
ROM_END
ROM_START( sblazerp )
@@ -529,6 +538,9 @@ ROM_START( sblazerp )
ROM_LOAD( "pr-5277.bin", 0x100, 0x100, CRC(bf2c33ab) SHA1(4a83b3e9b74b900621e8f42edf94cc04b791cdd0) )
ROM_LOAD( "pr-5276.bin", 0x200, 0x20, CRC(91267e8a) SHA1(ae5bd8efea5322c4d9986d06680a781392f9a642) )
ROM_LOAD( "pr-5275.bin", 0x220, 0x20, CRC(0c872a9b) SHA1(eaabce5d867a4e896bd356abc94429f9a4eec372) )
+
+ DISK_REGION( "laserdisc" )
+ DISK_IMAGE_READONLY( "sblazer", 0, NO_DUMP )
ROM_END
ROM_START( cobraseg )
@@ -557,6 +569,9 @@ ROM_START( cobraseg )
ROM_LOAD( "pr-5277.bin", 0x100, 0x100, CRC(bf2c33ab) SHA1(4a83b3e9b74b900621e8f42edf94cc04b791cdd0) )
ROM_LOAD( "pr-5276.bin", 0x200, 0x20, CRC(91267e8a) SHA1(ae5bd8efea5322c4d9986d06680a781392f9a642) )
ROM_LOAD( "pr-5275.bin", 0x220, 0x20, CRC(0c872a9b) SHA1(eaabce5d867a4e896bd356abc94429f9a4eec372) )
+
+ DISK_REGION( "laserdisc" )
+ DISK_IMAGE_READONLY( "cobracom", 0, NO_DUMP )
ROM_END
diff --git a/src/mame/drivers/superdq.c b/src/mame/drivers/superdq.c
index d14ba641eb7..790fec43e99 100644
--- a/src/mame/drivers/superdq.c
+++ b/src/mame/drivers/superdq.c
@@ -34,18 +34,6 @@ static UINT8 superdq_ld_out_latch;
static tilemap *superdq_tilemap;
static int superdq_color_bank = 0;
-static render_texture *video_texture;
-static render_texture *overlay_texture;
-static bitmap_t *last_video_bitmap;
-
-static void video_cleanup(running_machine *machine)
-{
- if (video_texture != NULL)
- render_texture_free(video_texture);
- if (overlay_texture != NULL)
- render_texture_free(overlay_texture);
-}
-
static TILE_GET_INFO( get_tile_info )
{
int tile = videoram[tile_index];
@@ -56,41 +44,13 @@ static TILE_GET_INFO( get_tile_info )
static VIDEO_START( superdq )
{
superdq_tilemap = tilemap_create(get_tile_info,tilemap_scan_rows, 8, 8, 32, 32);
-
- add_exit_callback(machine, video_cleanup);
}
static VIDEO_UPDATE( superdq )
{
- tilemap_draw(bitmap,cliprect,superdq_tilemap,0,0);
+ render_container_set_palette_alpha(render_container_get_screen(screen), 0, 0x00);
- if (!video_skip_this_frame())
- {
- bitmap_t *vidbitmap;
- rectangle fixedvis = *video_screen_get_visible_area(screen);
- fixedvis.max_x++;
- fixedvis.max_y++;
-
- laserdisc_get_video(laserdisc, &vidbitmap);
-
- /* first lay down the video data */
- if (video_texture == NULL)
- video_texture = render_texture_alloc(NULL, NULL);
- if (vidbitmap != last_video_bitmap)
- render_texture_set_bitmap(video_texture, vidbitmap, NULL, 0, TEXFORMAT_YUY16);
-
- last_video_bitmap = vidbitmap;
-
- /* then overlay the TMS9928A video */
- if (overlay_texture == NULL)
- overlay_texture = render_texture_alloc(NULL, NULL);
- render_texture_set_bitmap(overlay_texture, bitmap, &fixedvis, 0, TEXFORMAT_PALETTEA16);
-
- /* add both quads to the screen */
- render_container_empty(render_container_get_screen(screen));
- render_screen_add_quad(screen, 0.0f, 0.0f, 1.0f, 1.0f, MAKE_ARGB(0xff,0xff,0xff,0xff), video_texture, PRIMFLAG_BLENDMODE(BLENDMODE_NONE) | PRIMFLAG_SCREENTEX(1));
- render_screen_add_quad(screen, 0.0f, 0.0f, 1.0f, 1.0f, MAKE_ARGB(0xff,0xff,0xff,0xff), overlay_texture, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_SCREENTEX(1));
- }
+ tilemap_draw(bitmap,cliprect,superdq_tilemap,0,0);
/* display disc information */
popmessage("%s", laserdisc_describe_state(laserdisc));
@@ -349,23 +309,16 @@ static MACHINE_DRIVER_START( superdq )
MDRV_MACHINE_RESET(superdq)
MDRV_LASERDISC_ADD("laserdisc", PIONEER_LDV1000)
+ MDRV_LASERDISC_OVERLAY(superdq, 256, 256, BITMAP_FORMAT_INDEXED16)
/* video hardware */
- MDRV_VIDEO_ATTRIBUTES(VIDEO_SELF_RENDER)
-
- MDRV_SCREEN_ADD("main", RASTER)
- MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16)
- MDRV_SCREEN_REFRESH_RATE(60)
- MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0))
- MDRV_SCREEN_SIZE(32*8, 32*8)
- MDRV_SCREEN_VISIBLE_AREA(0*8, 32*8-1, 0*8, 32*8-1)
+ MDRV_LASERDISC_SCREEN_ADD_NTSC("main", BITMAP_FORMAT_INDEXED16)
MDRV_GFXDECODE(superdq)
MDRV_PALETTE_LENGTH(32)
MDRV_PALETTE_INIT(superdq)
MDRV_VIDEO_START(superdq)
- MDRV_VIDEO_UPDATE(superdq)
/* sound hardware */
MDRV_SPEAKER_STANDARD_STEREO("left", "right")
diff --git a/src/mame/drivers/thayers.c b/src/mame/drivers/thayers.c
index 83ab79be43d..7432b236e98 100644
--- a/src/mame/drivers/thayers.c
+++ b/src/mame/drivers/thayers.c
@@ -38,16 +38,6 @@ static int pr7820_enter;
static const UINT8 led_map[16] = { 0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7c, 0x07, 0x7f, 0x67, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x00 };
-/* Video */
-
-static VIDEO_UPDATE( thayers )
-{
- /* display disc information */
- popmessage("%s", laserdisc_describe_state(laserdisc));
-
- return 0;
-}
-
/* Interrupts */
static void check_interrupt(running_machine *machine)
@@ -772,15 +762,9 @@ static MACHINE_DRIVER_START( thayers )
MDRV_LASERDISC_ADD("laserdisc", PIONEER_PR7820)
/* video hardware */
- MDRV_SCREEN_ADD("main", RASTER)
- MDRV_SCREEN_FORMAT(BITMAP_FORMAT_RGB32)
- MDRV_SCREEN_REFRESH_RATE(60)
- MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) // inaccurate
- MDRV_SCREEN_SIZE(32*10, 32*8)
- MDRV_SCREEN_VISIBLE_AREA(0*10, 32*10-1, 0*8, 32*8-1)
+ MDRV_LASERDISC_SCREEN_ADD_NTSC("main", BITMAP_FORMAT_RGB32)
MDRV_PALETTE_LENGTH(256)
- MDRV_VIDEO_UPDATE(thayers)
/* sound hardware */
// SSI 263 @ 2MHz
diff --git a/src/mame/includes/gottlieb.h b/src/mame/includes/gottlieb.h
index c4970469e59..7e79bfa67ac 100644
--- a/src/mame/includes/gottlieb.h
+++ b/src/mame/includes/gottlieb.h
@@ -38,6 +38,4 @@ extern WRITE8_HANDLER( gottlieb_laserdisc_video_control_w );
extern WRITE8_HANDLER( gottlieb_paletteram_w );
VIDEO_START( gottlieb );
-VIDEO_START( gottlieb_laserdisc );
VIDEO_UPDATE( gottlieb );
-VIDEO_UPDATE( gottlieb_laserdisc );
diff --git a/src/mame/mame.mak b/src/mame/mame.mak
index 74b92ddcce2..c5452d67894 100644
--- a/src/mame/mame.mak
+++ b/src/mame/mame.mak
@@ -137,6 +137,7 @@ CPUS += UPD7807
CPUS += ARM
CPUS += ARM7
CPUS += JAGUAR
+CPUS += CUBEQCPU
CPUS += R3000
CPUS += R3041
CPUS += R4600
@@ -1536,6 +1537,7 @@ $(MAMEOBJ)/misc.a: \
$(DRIVERS)/coolpool.o \
$(DRIVERS)/cowrace.o \
$(DRIVERS)/crystal.o $(VIDEO)/vrender0.o \
+ $(DRIVERS)/cubeqst.o \
$(DRIVERS)/cybertnk.o \
$(DRIVERS)/dcheese.o $(VIDEO)/dcheese.o \
$(DRIVERS)/dgpix.o \
diff --git a/src/mame/mamedriv.c b/src/mame/mamedriv.c
index 0b35e2ca765..d4991e3f910 100644
--- a/src/mame/mamedriv.c
+++ b/src/mame/mamedriv.c
@@ -7938,6 +7938,7 @@ Other Sun games
DRIVER( ttchampa )
DRIVER( dreamwld ) /* (c) 2000 SemiCom */
DRIVER( cybertnk ) /* (c) 1990 Coreland */
+ DRIVER( cubeqst ) /* (c) 1983 Simutrek Inc. */
DRIVER( pkscram ) /* (c) 1993 Cosmo Electronics Corporation */
/* Funworld */
diff --git a/src/mame/video/gottlieb.c b/src/mame/video/gottlieb.c
index 55c67304654..be11ac78fc4 100644
--- a/src/mame/video/gottlieb.c
+++ b/src/mame/video/gottlieb.c
@@ -20,11 +20,6 @@ static UINT8 spritebank;
static tilemap *bg_tilemap;
static double weights[4];
-static render_texture *video_texture;
-static render_texture *overlay_texture;
-static const rectangle overlay_clip = { 0, GOTTLIEB_VIDEO_HBLANK-1, 0, GOTTLIEB_VIDEO_VBLANK-8 };
-
-
/*************************************
*
@@ -86,6 +81,8 @@ WRITE8_HANDLER( gottlieb_video_control_w )
WRITE8_HANDLER( gottlieb_laserdisc_video_control_w )
{
+ const device_config *laserdisc = device_list_first(machine->config->devicelist, LASERDISC);
+
/* bit 0 works like the other games */
gottlieb_video_control_w(machine, offset, data & 0x01);
@@ -93,8 +90,10 @@ WRITE8_HANDLER( gottlieb_laserdisc_video_control_w )
spritebank = (data & 0x02) >> 1;
/* bit 2 video enable (0 = black screen) */
-
/* bit 3 genlock control (1 = show laserdisc image) */
+ laserdisc_overlay_enable(laserdisc, (data & 0x04) ? TRUE : FALSE);
+ laserdisc_video_enable(laserdisc, ((data & 0x0c) == 0x0c) ? TRUE : FALSE);
+
render_container_set_palette_alpha(render_container_get_screen(machine->primary_screen), 0, (data & 0x08) ? 0x00 : 0xff);
}
@@ -164,23 +163,6 @@ VIDEO_START( gottlieb )
}
-VIDEO_START( gottlieb_laserdisc )
-{
- /* handle normal video */
- VIDEO_START_CALL(gottlieb);
-
- /* allocate an overlay texture */
- overlay_texture = render_texture_alloc(NULL, NULL);
- if (overlay_texture == NULL)
- fatalerror("Out of memory allocating overlay texture");
-
- /* allocate a video texture */
- video_texture = render_texture_alloc(NULL, NULL);
- if (video_texture == NULL)
- fatalerror("Out of memory allocating video texture");
-}
-
-
/*************************************
*
@@ -237,37 +219,3 @@ VIDEO_UPDATE( gottlieb )
return 0;
}
-
-
-VIDEO_UPDATE( gottlieb_laserdisc )
-{
- const device_config *laserdisc = device_list_first(screen->machine->config->devicelist, LASERDISC);
- rectangle clip = *cliprect;
- bitmap_t *video_bitmap;
-
- /* scale the cliprect to the screen and render it */
- clip.min_x = 0;
- clip.max_x = GOTTLIEB_VIDEO_HBLANK - 1;
- clip.min_y = cliprect->min_y * GOTTLIEB_VIDEO_VCOUNT / bitmap->height;
- clip.max_y = (cliprect->max_y + 1) * GOTTLIEB_VIDEO_VCOUNT / bitmap->height - 1;
- video_update_gottlieb(screen, bitmap, &clip);
-
- /* if this is the last update, handle it */
- if (cliprect->max_y == video_screen_get_visible_area(screen)->max_y)
- {
- /* update the texture with the overlay contents */
- render_texture_set_bitmap(overlay_texture, bitmap, &overlay_clip, 0, TEXFORMAT_PALETTEA16);
-
- /* now talk to the laserdisc */
- laserdisc_get_video(laserdisc, &video_bitmap);
- if (video_bitmap != NULL)
- render_texture_set_bitmap(video_texture, video_bitmap, NULL, 0, TEXFORMAT_YUY16);
-
- /* add both quads to the screen */
- render_container_empty(render_container_get_screen(screen));
- render_screen_add_quad(screen, 0.0f, 0.0f, 1.0f, 1.0f, MAKE_ARGB(0xff,0xff,0xff,0xff), video_texture, PRIMFLAG_BLENDMODE(BLENDMODE_NONE) | PRIMFLAG_SCREENTEX(1));
- render_screen_add_quad(screen, 0.0f, 0.0f, 1.0f, 1.0f, MAKE_ARGB(0xff,0xff,0xff,0xff), overlay_texture, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_SCREENTEX(1));
- }
-
- return 0;
-}
diff --git a/src/tools/chdcd.c b/src/tools/chdcd.c
index 008092bb859..3a436b257a9 100644
--- a/src/tools/chdcd.c
+++ b/src/tools/chdcd.c
@@ -119,6 +119,115 @@ static int msf_to_frames( char *token )
return f;
}
+chd_error chdcd_parse_gdi(const char *tocfname, cdrom_toc *outtoc, chdcd_track_input_info *outinfo)
+{
+ FILE *infile;
+ int i, numtracks;
+ int chdpos=0;
+
+ infile = fopen(tocfname, "rt");
+
+ if (infile == (FILE *)NULL)
+ {
+ return CHDERR_FILE_NOT_FOUND;
+ }
+
+ /* clear structures */
+ memset(outtoc, 0, sizeof(cdrom_toc));
+ memset(outinfo, 0, sizeof(chdcd_track_input_info));
+
+
+ fgets(linebuffer,511,infile);
+ numtracks=atoi(linebuffer);
+
+ for(i=0;i<numtracks;++i)
+ {
+ char *tok;
+ int trknum;
+ int trksize,trktype;
+ int sz;
+ int hunks;
+
+
+ fgets(linebuffer,511,infile);
+
+ tok=strtok(linebuffer," ");
+
+ trknum=atoi(tok)-1;
+
+ outinfo->swap[trknum]=0;
+ outinfo->offset[trknum]=0;
+
+ //outtoc->tracks[trknum].trktype = CD_TRACK_MODE1;
+ outtoc->tracks[trknum].datasize = 0;
+ outtoc->tracks[trknum].subtype = CD_SUB_NONE;
+ outtoc->tracks[trknum].subsize = 0;
+
+ tok=strtok(NULL," ");
+ outtoc->tracks[trknum].physframeofs=atoi(tok);
+
+ tok=strtok(NULL," ");
+ trktype=atoi(tok);
+
+ tok=strtok(NULL," ");
+ trksize=atoi(tok);
+
+ if(trktype==4 && trksize==2352)
+ {
+ outtoc->tracks[trknum].trktype=CD_TRACK_MODE1_RAW;
+ outtoc->tracks[trknum].datasize=2352;
+ }
+ if(trktype==4 && trksize==2048)
+ {
+ outtoc->tracks[trknum].trktype=CD_TRACK_MODE1;
+ outtoc->tracks[trknum].datasize=2048;
+ }
+ if(trktype==0)
+ {
+ //assert(trksize==2352);
+ outtoc->tracks[trknum].trktype=CD_TRACK_AUDIO;
+ outtoc->tracks[trknum].datasize=2352;
+ }
+
+ tok=strtok(NULL," ");
+ strcpy(&(outinfo->fname[trknum][0]),tok);
+ sz=get_file_size(outinfo->fname[trknum]);
+
+ outtoc->tracks[trknum].frames=sz/trksize;
+ outtoc->tracks[trknum].extraframes=0;
+
+ if(trknum!=0)
+ {
+ int dif=outtoc->tracks[trknum].physframeofs-(outtoc->tracks[trknum-1].frames+outtoc->tracks[trknum-1].physframeofs);
+ outtoc->tracks[trknum-1].frames+=dif;
+ }
+
+/*
+ if(trknum!=0)
+ {
+ outtoc->tracks[trknum-1].extraframes=outtoc->tracks[trknum].physframeofs-(outtoc->tracks[trknum-1].frames+outtoc->tracks[trknum-1].physframeofs);
+ }
+*/
+ hunks = (outtoc->tracks[trknum].frames+CD_FRAMES_PER_HUNK - 1) / CD_FRAMES_PER_HUNK;
+ outtoc->tracks[trknum].extraframes = hunks * CD_FRAMES_PER_HUNK - outtoc->tracks[trknum].frames;
+
+ chdpos+=outtoc->tracks[trknum].frames+outtoc->tracks[trknum].extraframes;
+
+ }
+ /*
+ for(i=0;i<numtracks;++i)
+ {
+ printf("%s %d %d %d\n",outinfo->fname[i],outtoc->tracks[i].frames,outtoc->tracks[i].extraframes,outtoc->tracks[i].physframeofs);
+ }
+ */
+ /* close the input TOC */
+ fclose(infile);
+
+ /* store the number of tracks found */
+ outtoc->numtrks = numtracks;
+
+ return CHDERR_NONE;
+}
/*-------------------------------------------------
chdcd_parse_toc - parse a CDRDAO format TOC file
@@ -130,6 +239,11 @@ chd_error chdcd_parse_toc(const char *tocfname, cdrom_toc *outtoc, chdcd_track_i
int i, trknum;
static char token[128];
+ if (strstr(tocfname,".gdi"))
+ {
+ return chdcd_parse_gdi(tocfname, outtoc, outinfo);
+ }
+
infile = fopen(tocfname, "rt");
if (infile == (FILE *)NULL)
diff --git a/src/tools/chdman.c b/src/tools/chdman.c
index cc079f20bce..068c919c8d6 100644
--- a/src/tools/chdman.c
+++ b/src/tools/chdman.c
@@ -133,8 +133,8 @@ static void ATTR_PRINTF(2,3) progress(int forceit, const char *fmt, ...)
/* standard vfprintf stuff here */
va_start(arg, fmt);
- vprintf(fmt, arg);
- fflush(stdout);
+ vfprintf(stderr, fmt, arg);
+ fflush(stderr);
va_end(arg);
}
diff --git a/src/tools/ldverify.c b/src/tools/ldverify.c
index 8aea954576f..41b10630950 100644
--- a/src/tools/ldverify.c
+++ b/src/tools/ldverify.c
@@ -19,6 +19,14 @@
/***************************************************************************
+ CONSTANTS
+***************************************************************************/
+
+#define REPORT_BLANKS_THRESHOLD 8
+
+
+
+/***************************************************************************
TYPE DEFINITIONS
***************************************************************************/
@@ -52,6 +60,9 @@ static UINT32 video_cadence_history = 0;
static int video_prev_whitefield = -1;
static int video_min_overall = 255;
static int video_max_overall = 0;
+static int video_first_blank_frame = -1;
+static int video_first_blank_field = -1;
+static int video_num_blank_fields = -1;
static int video_first_low_frame = -1;
static int video_first_low_field = -1;
static int video_num_low_fields = -1;
@@ -307,9 +318,12 @@ static void verify_video(int frame, bitmap_t *bitmap)
/* loop over fields */
for (fieldnum = 0; fieldnum < fields_per_frame; fieldnum++)
{
+ int yminval, ymaxval, cbminval, cbmaxval, crminval, crmaxval;
int field = frame * fields_per_frame + fieldnum;
- int x, y, pixels, remaining, minval, maxval;
- UINT32 pixelhisto[256] = { 0 };
+ int x, y, pixels, remaining;
+ UINT32 yhisto[256] = { 0 };
+ UINT32 crhisto[256] = { 0 };
+ UINT32 cbhisto[256] = { 0 };
vbi_metadata metadata;
/* output status */
@@ -464,24 +478,63 @@ static void verify_video(int frame, bitmap_t *bitmap)
for (y = 22*2 + fieldnum; y < bitmap->height; y += 2)
{
for (x = 16; x < 720 - 16; x++)
- pixelhisto[*BITMAP_ADDR16(bitmap, y, x) >> 8]++;
+ {
+ yhisto[*BITMAP_ADDR16(bitmap, y, x) >> 8]++;
+ if (x % 2 == 0)
+ cbhisto[*BITMAP_ADDR16(bitmap, y, x) & 0xff]++;
+ else
+ crhisto[*BITMAP_ADDR16(bitmap, y, x) & 0xff]++;
+ }
pixels += 720 - 16 - 16;
}
- /* remove the top/bottom 0.1% */
+ /* remove the top/bottom 0.1% of Y */
remaining = pixels / 1000;
- for (minval = 0; remaining >= 0; minval++)
- remaining -= pixelhisto[minval];
+ for (yminval = 0; remaining >= 0; yminval++)
+ remaining -= yhisto[yminval];
remaining = pixels / 1000;
- for (maxval = 255; remaining >= 0; maxval--)
- remaining -= pixelhisto[maxval];
+ for (ymaxval = 255; remaining >= 0; ymaxval--)
+ remaining -= yhisto[ymaxval];
+
+ /* remove the top/bottom 0.1% of Cb */
+ remaining = pixels / 500;
+ for (cbminval = 0; remaining >= 0; cbminval++)
+ remaining -= cbhisto[cbminval];
+ remaining = pixels / 500;
+ for (cbmaxval = 255; remaining >= 0; cbmaxval--)
+ remaining -= cbhisto[cbmaxval];
+
+ /* remove the top/bottom 0.1% of Cr */
+ remaining = pixels / 500;
+ for (crminval = 0; remaining >= 0; crminval++)
+ remaining -= crhisto[crminval];
+ remaining = pixels / 500;
+ for (crmaxval = 255; remaining >= 0; crmaxval--)
+ remaining -= crhisto[crmaxval];
+
+ /* track blank frames */
+ if (ymaxval - yminval < 10 && cbmaxval - cbminval < 10 && crmaxval - cbmaxval < 10)
+ {
+ if (video_first_blank_frame == -1)
+ {
+ video_first_blank_frame = frame;
+ video_first_blank_field = fieldnum;
+ video_num_blank_fields = 0;
+ }
+ video_num_blank_fields++;
+ }
+ else if (video_num_blank_fields >= REPORT_BLANKS_THRESHOLD)
+ {
+ printf("%6d.%d-%6d.%d: blank frames for %d fields (INFO)\n", video_first_blank_frame, video_first_blank_field, frame, fieldnum, video_num_blank_fields);
+ video_first_blank_frame = video_first_blank_field = video_num_blank_fields = -1;
+ }
/* update the overall min/max */
- video_min_overall = MIN(minval, video_min_overall);
- video_max_overall = MAX(maxval, video_max_overall);
+ video_min_overall = MIN(yminval, video_min_overall);
+ video_max_overall = MAX(ymaxval, video_max_overall);
/* track low fields */
- if (minval < 16)
+ if (yminval < 16)
{
if (video_first_low_frame == -1)
{
@@ -498,7 +551,7 @@ static void verify_video(int frame, bitmap_t *bitmap)
}
/* track high fields */
- if (maxval > 236)
+ if (ymaxval > 236)
{
if (video_first_high_frame == -1)
{
@@ -535,6 +588,8 @@ static void verify_video_final(int frame, bitmap_t *bitmap)
printf("Track %6d.%d: never saw any lead-out (WARNING)\n", field / fields_per_frame, 0);
/* any remaining high/low reports? */
+ if (video_num_blank_fields >= REPORT_BLANKS_THRESHOLD)
+ printf("%6d.%d-%6d.%d: blank frames for %d fields (INFO)\n", video_first_blank_frame, video_first_blank_field, frame, 0, video_num_blank_fields);
if (video_num_low_fields > 0)
printf("%6d.%d-%6d.%d: active video signal level low for %d fields (WARNING)\n", video_first_low_frame, video_first_low_field, frame, 0, video_num_low_fields);
if (video_num_high_fields > 0)