summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--android-project/app/src/main/AndroidManifest.xml4
-rw-r--r--makefile4
2 files changed, 4 insertions, 4 deletions
diff --git a/android-project/app/src/main/AndroidManifest.xml b/android-project/app/src/main/AndroidManifest.xml
index 372a7660567..5c7239dfbcc 100644
--- a/android-project/app/src/main/AndroidManifest.xml
+++ b/android-project/app/src/main/AndroidManifest.xml
@@ -4,8 +4,8 @@
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.mamedev.mame"
- android:versionCode="212"
- android:versionName="0.212"
+ android:versionCode="213"
+ android:versionName="0.213"
android:installLocation="auto">
<!-- OpenGL ES 2.0 -->
diff --git a/makefile b/makefile
index 464572331c7..9166b1423be 100644
--- a/makefile
+++ b/makefile
@@ -1645,14 +1645,14 @@ endif
ifeq (posix,$(SHELLTYPE))
$(GENDIR)/version.cpp: $(GENDIR)/git_desc | $(GEN_FOLDERS)
- @echo '#define BARE_BUILD_VERSION "0.212"' > $@
+ @echo '#define BARE_BUILD_VERSION "0.213"' > $@
@echo 'extern const char bare_build_version[];' >> $@
@echo 'extern const char build_version[];' >> $@
@echo 'const char bare_build_version[] = BARE_BUILD_VERSION;' >> $@
@echo 'const char build_version[] = BARE_BUILD_VERSION " ($(NEW_GIT_VERSION))";' >> $@
else
$(GENDIR)/version.cpp: $(GENDIR)/git_desc
- @echo #define BARE_BUILD_VERSION "0.212" > $@
+ @echo #define BARE_BUILD_VERSION "0.213" > $@
@echo extern const char bare_build_version[]; >> $@
@echo extern const char build_version[]; >> $@
@echo const char bare_build_version[] = BARE_BUILD_VERSION; >> $@
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337
// license:BSD-3-Clause
// copyright-holders:Joakim Larsson Edstrom
#ifndef __FGA002_H__
#define __FGA002_H__

#include "cpu/m68000/m68000.h" // The FGA002 is designed for the 68K interrupt PL0-PL2 signalling, however used on Sparc and x86 boards too

#define MCFG_FGA002_ADD(_tag, _clock)   MCFG_DEVICE_ADD(_tag, FGA002, _clock)

// LOCAL IRQ callbacks
#define MCFG_FGA002_OUT_INT_CB(_devcb)                              \
	devcb = &fga002_device::set_out_int_callback(*device, DEVCB_##_devcb);

#define MCFG_FGA002_OUT_LIACK4_CB(_devcb)                               \
	devcb = &fga002_device::set_liack4_callback(*device, DEVCB_##_devcb);

#define MCFG_FGA002_OUT_LIACK5_CB(_devcb)                               \
	devcb = &fga002_device::set_liack5_callback(*device, DEVCB_##_devcb);

#define MCFG_FGA002_OUT_LIACK6_CB(_devcb)                               \
	devcb = &fga002_device::set_liack6_callback(*device, DEVCB_##_devcb);

#define MCFG_FGA002_OUT_LIACK7_CB(_devcb)                               \
	devcb = &fga002_device::set_liack7_callback(*device, DEVCB_##_devcb);

// type for array of mapping of FGA registers that assembles an IRQ source
typedef struct {
	int vector;
	int status;
	int control;
} fga_irq_t;

//**************************************************************************
//  TYPE DEFINITIONS
//**************************************************************************

// ======================> fga002_device

class fga002_device :  public device_t
//      ,public device_z80daisy_interface
{
	public:
	// construction/destruction
	fga002_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, uint32_t clock, uint32_t variant, const char *shortname, const char *source);
	fga002_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);

	DECLARE_WRITE8_MEMBER (write);
	DECLARE_READ8_MEMBER (read);

	void lirq_w(int status, int vector, int control, int state);
	DECLARE_WRITE_LINE_MEMBER( lirq0_w );
	DECLARE_WRITE_LINE_MEMBER( lirq1_w );
	DECLARE_WRITE_LINE_MEMBER( lirq2_w );
	DECLARE_WRITE_LINE_MEMBER( lirq3_w );
	DECLARE_WRITE_LINE_MEMBER( lirq4_w );
	DECLARE_WRITE_LINE_MEMBER( lirq5_w );
	DECLARE_WRITE_LINE_MEMBER( lirq6_w );
	DECLARE_WRITE_LINE_MEMBER( lirq7_w );

	IRQ_CALLBACK_MEMBER(iack);
	int acknowledge();
	int get_irq_level();

	template<class _Object> static devcb_base &set_out_int_callback(device_t &device, _Object object) { return downcast<fga002_device &>(device).m_out_int_cb.set_callback(object); }
	template<class _Object> static devcb_base &set_liack4_callback(device_t &device, _Object object) { return downcast<fga002_device &>(device).m_liack4_cb.set_callback(object); }
	template<class _Object> static devcb_base &set_liack5_callback(device_t &device, _Object object) { return downcast<fga002_device &>(device).m_liack5_cb.set_callback(object); }
	template<class _Object> static devcb_base &set_liack6_callback(device_t &device, _Object object) { return downcast<fga002_device &>(device).m_liack6_cb.set_callback(object); }
	template<class _Object> static devcb_base &set_liack7_callback(device_t &device, _Object object) { return downcast<fga002_device &>(device).m_liack7_cb.set_callback(object); }

	// interrupt sources in prio order if on same interrupt level. TODO: Add all sources
	const static fga_irq_t m_irq_sources[];

 protected:
	// device-level overrides
	virtual void device_start() override;
	virtual void device_reset() override;
#if 0
	// device_z80daisy_interface overrides
	virtual int z80daisy_irq_state() override;
	virtual int z80daisy_irq_ack() override;
	virtual void z80daisy_irq_reti() override;
#endif
	virtual void device_timer (emu_timer &timer, device_timer_id id, int param, void *ptr) override;

	devcb_write_line    m_out_int_cb;
	devcb_read8         m_liack4_cb;
	devcb_read8         m_liack5_cb;
	devcb_read8         m_liack6_cb;
	devcb_read8         m_liack7_cb;
	int m_int_state[0x08]; // interrupt state

 private:

	uint8_t m_tim0count;
	uint8_t   m_fga002[0x500];

	uint8_t do_fga002reg_ctl3_r();
	void do_fga002reg_ctl3_w(uint8_t data);

	/* Timer functions */
	uint8_t do_fga002reg_tim0preload_r();
	void  do_fga002reg_tim0preload_w(uint8_t data);
	uint8_t do_fga002reg_tim0ctl_r();
	void  do_fga002reg_tim0ctl_w(uint8_t data);
	uint8_t do_fga002reg_tim0count_r();
	void  do_fga002reg_tim0count_w(uint8_t data);
	uint8_t do_fga002reg_icrtim0_r();
	void  do_fga002reg_icrtim0_w(uint8_t data);
	uint8_t do_fga002reg_istim0_r();
	void  do_fga002reg_istim0_w(uint8_t data);
	emu_timer *fga_timer;
	enum
	{
		TIMER_ID_FGA
	};
	enum {
		REG_TIM0CTL_ZERO_STOP   = 0x80,
		REG_TIM0CTL_AUTOPRELOAD = 0x40,
		REG_TIM0CTL_SYSFAIL     = 0x20,
		REG_TIM0CTL_START_STOP  = 0x10,
		REG_TIM0CTL_CLK_MSK     = 0x0f,
		REG_TIM0CTL_CLK_1_MIC   = 0x00,
		REG_TIM0CTL_CLK_2_MIC   = 0x01,
		REG_TIM0CTL_CLK_4_MIC   = 0x02,
		REG_TIM0CTL_CLK_8_MIC   = 0x03,
		REG_TIM0CTL_CLK_16_MIC  = 0x04,
		REG_TIM0CTL_CLK_32_MIC  = 0x05,
		REG_TIM0CTL_CLK_64_MIC  = 0x06,
		REG_TIM0CTL_CLK_128_MIC = 0x07,
		REG_TIM0CTL_CLK_256_MIC = 0x08,
		REG_TIM0CTL_CLK_512_MIC = 0x09,
		REG_TIM0CTL_CLK_2_MIL   = 0x0a,
		REG_TIM0CTL_CLK_8_MIL   = 0x0b,
		REG_TIM0CTL_CLK_32_MIL  = 0x0c,
		REG_TIM0CTL_CLK_125_MIL = 0x0d,
		REG_TIM0CTL_CLK_500_MIL = 0x0e,
		REG_TIM0CTL_CLK_2_SEC   = 0x0f,
	};
	enum {
		REG_ISTIM0_TIM_INT  = 0x80,
	};

	/* Interrupt support */
	uint8_t m_irq_level;
	uint8_t do_fga002reg_localiack_r();
	void do_fga002reg_localiack_w(uint8_t data);

	uint8_t do_fga002reg_islocal0_r();
	uint8_t do_fga002reg_islocal1_r();
	uint8_t do_fga002reg_islocal2_r();
	uint8_t do_fga002reg_islocal3_r();
	uint8_t do_fga002reg_islocal4_r();
	uint8_t do_fga002reg_islocal5_r();
	uint8_t do_fga002reg_islocal6_r();
	uint8_t do_fga002reg_islocal7_r();

	void islocal_w(int status, int vector, int control, int data);
	void  do_fga002reg_islocal0_w(uint8_t data);
	void  do_fga002reg_islocal1_w(uint8_t data);
	void  do_fga002reg_islocal2_w(uint8_t data);
	void  do_fga002reg_islocal3_w(uint8_t data);
	void  do_fga002reg_islocal4_w(uint8_t data);
	void  do_fga002reg_islocal5_w(uint8_t data);
	void  do_fga002reg_islocal6_w(uint8_t data);
	void  do_fga002reg_islocal7_w(uint8_t data);

	uint8_t do_fga002reg_icrlocal0_r();
	uint8_t do_fga002reg_icrlocal1_r();
	uint8_t do_fga002reg_icrlocal2_r();
	uint8_t do_fga002reg_icrlocal3_r();
	uint8_t do_fga002reg_icrlocal4_r();
	uint8_t do_fga002reg_icrlocal5_r();
	uint8_t do_fga002reg_icrlocal6_r();
	uint8_t do_fga002reg_icrlocal7_r();
	void  do_fga002reg_icrlocal0_w(uint8_t data);
	void  do_fga002reg_icrlocal1_w(uint8_t data);
	void  do_fga002reg_icrlocal2_w(uint8_t data);
	void  do_fga002reg_icrlocal3_w(uint8_t data);
	void  do_fga002reg_icrlocal4_w(uint8_t data);
	void  do_fga002reg_icrlocal5_w(uint8_t data);
	void  do_fga002reg_icrlocal6_w(uint8_t data);
	void  do_fga002reg_icrlocal7_w(uint8_t data);

	void trigger_interrupt(uint8_t data);
	void check_interrupts();

	enum {
		REG_ISLOCAL_IRQ = 0x80
	};

	enum {
		REG_CTL3_VECTORBITS7_6 = 0x0c
	};

	enum{
		REG_LIACK_LOCAL4_MSK    = 0x03,
		REG_LIACK_LOCAL5_MSK    = 0x0c, // >> 2 to use patterns below
		REG_LIACK_LOCAL6_MSK    = 0x30, // >> 4 to use patterns below
		REG_LIACK_LOCAL7_MSK    = 0xc0, // >> 6 to use patterns below
		REG_LIACK_INT_IACK      = 0x00, // Assumes bits to be right adjusted
		REG_LIACK_EXT_IACK1     = 0x01,
		REG_LIACK_EXT_IACK2     = 0x02,
		REG_LIACK_EXT_IACK3     = 0x03,
	};

	enum{
		INT_LOCAL0 = 0x30,
		INT_LOCAL1 = 0x31,
		INT_LOCAL2 = 0x32,
		INT_LOCAL3 = 0x33,
		INT_LOCAL4 = 0x34,
		INT_LOCAL5 = 0x35,
		INT_LOCAL6 = 0x36,
		INT_LOCAL7 = 0x37,
		INT_EMPTY  = 0x3F,
		INT_ACK_AUTOVECTOR  = -1,
	};

	enum{
		REG_ICR_LVL_MSK     = 0x07,
		REG_ICR_ENABLE      = 0x08,
		REG_ICR_AUTOCLR     = 0x10,
		REG_ICR_ACTIVITY    = 0x20,
		REG_ICR_EDGE        = 0x40,
	};

	/* Register offsets */
	enum {
		FGA_ICRMBOX0    = 0x0000,
		FGA_ICRMBOX1    = 0x0004,
		FGA_ICRMBOX2    = 0x0008,
		FGA_ICRMBOX3    = 0x000c,
		FGA_ICRMBOX4    = 0x0010,
		FGA_ICRMBOX5    = 0x0014,
		FGA_ICRMBOX6    = 0x0018,
		FGA_ICRMBOX7    = 0x001C,
		FGA_VMEPAGE     = 0x0200,
		FGA_ICRVME1     = 0x0204,
		FGA_ICRVME2     = 0x0208,
		FGA_ICRVME3     = 0x020c,
		FGA_ICRVME4     = 0x0210,
		FGA_ICRVME5     = 0x0214,
		FGA_ICRVME6     = 0x0218,
		FGA_ICRVME7     = 0x021c,
		FGA_ICRTIM0     = 0x0220,
		FGA_ICRDMANORM  = 0x0230,
		FGA_ICRDMAERR   = 0x0234,
		FGA_CTL1        = 0x0238,
		FGA_CTL2        = 0x023c,
		FGA_ICRFMB0REF  = 0x0240,
		FGA_ICRFMB1REF  = 0x0244,
		FGA_ICRFMB0MES  = 0x0248,
		FGA_ICRFMB1MES  = 0x024c,
		FGA_CTL3        = 0x0250,
		FGA_CTL4        = 0x0254,
		FGA_ICRPARITY   = 0x0258,
		FGA_AUXPINCTL   = 0x0260,
		FGA_CTL5        = 0x0264,
		FGA_AUXFIFWEX   = 0x0268,
		FGA_AUXFIFREX   = 0x026c,
		FGA_CTL6        = 0x0270,
		FGA_CTL7        = 0x0274,
		FGA_CTL8        = 0x0278,
		FGA_CTL9        = 0x027c,
		FGA_ICRABORT    = 0x0280,
		FGA_ICRACFAIL   = 0x0284,
		FGA_ICRSYSFAIL  = 0x0288,
		FGA_ICRLOCAL0   = 0x028c,
		FGA_ICRLOCAL1   = 0x0290,
		FGA_ICRLOCAL2   = 0x0294,
		FGA_ICRLOCAL3   = 0x0298,
		FGA_ICRLOCAL4   = 0x029c,
		FGA_ICRLOCAL5   = 0x02a0,
		FGA_ICRLOCAL6   = 0x02a4,
		FGA_ICRLOCAL7   = 0x02a8,
		FGA_ENAMCODE    = 0x02b4,
		FGA_CTL10       = 0x02c0,
		FGA_CTL11       = 0x02c4,
		FGA_MAINUM      = 0x02c8,
		FGA_MAINUU      = 0x02cc,
		FGA_BOTTOMPAGEU = 0x02d0,
		FGA_BOTTOMPAGEL = 0x02d4,
		FGA_TOPPAGEU    = 0x02d8,
		FGA_TOPPAGEL    = 0x02dc,
		FGA_MYVMEPAGE   = 0x02fc,
		FGA_TIM0PRELOAD = 0x0300,
		FGA_TIM0CTL     = 0x0310,
		FGA_DMASRCATT   = 0x0320,
		FGA_DMADSTATT   = 0x0324,
		FGA_DMA_GENERAL = 0x0328,
		FGA_CTL12       = 0x032c,
		FGA_LIOTIMING   = 0x0330,
		FGA_LOCALIACK   = 0x0334,
		FGA_FMBCTL      = 0x0338,
		FGA_FMBAREA     = 0x033c,
		FGA_AUXSRCSTART = 0x0340,
		FGA_AUXDSTSTART = 0x0344,
		FGA_AUXSRCTERM  = 0x0348,
		FGA_AUXDSTTERM  = 0x034c,
		FGA_CTL13       = 0x0350,
		FGA_CTL14       = 0x0354,
		FGA_CTL15       = 0x0358,
		FGA_CTL16       = 0x035c,
		FGA_SPECIALENA  = 0x0424,
		FGA_ISLOCAL0    = 0x0480,
		FGA_ISLOCAL1    = 0x0484,
		FGA_ISLOCAL2    = 0x0488,
		FGA_ISLOCAL3    = 0x048C,
		FGA_ISLOCAL4    = 0x0490,
		FGA_ISLOCAL5    = 0x0494,
		FGA_ISLOCAL6    = 0x0498,
		FGA_ISLOCAL7    = 0x049C,
		FGA_ISTIM0      = 0x04a0,
		FGA_ISDMANORM   = 0x04b0,
		FGA_ISDMAERR    = 0x04b4,
		FGA_ISFMB0REF   = 0x04b8,
		FGA_ISFMB1REF   = 0x04bc,
		FGA_ISPARITY    = 0x04c0,
		FGA_DMARUNCTL   = 0x04c4,
		FGA_ISABORT     = 0x04c8,
		FGA_ISACFAIL    = 0x04cc,
		FGA_ISFMB0MES   = 0x04e0,
		FGA_ISFMB1MES   = 0x04e4,
		FGA_ISSYSFAIL   = 0x04d0,
		FGA_ABORTPIN    = 0x04d4,
		FGA_RSVMECALL   = 0x04f0,
		FGA_RSKEYRES    = 0x04f4,
		FGA_RSCPUCALL   = 0x04f8,
		FGA_RSLOCSW     = 0x04fc,
		FGA_TIM0COUNT   = 0x0c00,
	};
};


// device type definition
extern const device_type FGA002;
#endif // __FGA002_H__
n class="cm">/* 0x */ "undef","undef","WPTN ","RPTN ", /* 1x */ "undef","DRD ","DWT ","DMOD ", /* 2x */ "undef","undef","undef","undef", /* 3x */ "undef","RD ","WT ","MOD ", /* 4x */ "undef","undef","CLR ","SCLR ", /* 5x */ "CPY ","CPY ","CPY ","CPY ", /* 6x */ "SCPY ","SCPY ","SCPY ","SCPY ", /* 7x */ "AMOVE","RMOVE","ALINE","RLINE", /* 8x */ "ARCT ","RRCT ","APLL ","RPLL ", /* 9x */ "APLG ","RPLG ","CRCL ","ELPS ", /* Ax */ "AARC ","RARC ","AEARC","REARC", /* Bx */ "AFRCT","RFRCT","PAINT","DOT ", /* Cx */ "PTN ","PTN ","PTN ","PTN ", /* Dx */ "AGCPY","AGCPY","AGCPY","AGCPY", /* Ex */ "RGCPY","RGCPY","RGCPY","RGCPY" /* Fx */ }; static void doclr16( device_t *device, int opcode, UINT16 fill, int *dst, INT16 _ax, INT16 _ay ) { hd63484_state *hd63484 = get_safe_token(device); INT16 ax,ay; ax = _ax; ay = _ay; for (;;) { for (;;) { switch (opcode & 0x0003) { case 0: hd63484->ram[*dst] = fill; break; case 1: hd63484->ram[*dst] |= fill; break; case 2: hd63484->ram[*dst] &= fill; break; case 3: hd63484->ram[*dst] ^= fill; break; } if (ax == 0) break; else if (ax > 0) { *dst = (*dst + 1) & (HD63484_RAM_SIZE - 1); ax--; } else { *dst = (*dst - 1) & (HD63484_RAM_SIZE - 1); ax++; } } ax = _ax; if (_ay < 0) { *dst = (*dst + (hd63484->reg[0xca/2] & 0x0fff) - ax) & (HD63484_RAM_SIZE - 1); if (ay == 0) break; ay++; } else { *dst = (*dst - (hd63484->reg[0xca/2] & 0x0fff) - ax) & (HD63484_RAM_SIZE - 1); if (ay == 0) break; ay--; } } } static void docpy16( device_t *device, int opcode, int src, int *dst, INT16 _ax, INT16 _ay ) { hd63484_state *hd63484 = get_safe_token(device); int dstep1,dstep2; int ax = _ax; int ay = _ay; switch (opcode & 0x0700) { default: case 0x0000: dstep1 = 1; dstep2 = -1 * (hd63484->reg[0xca/2] & 0x0fff) - ax * dstep1; break; case 0x0100: dstep1 = 1; dstep2 = (hd63484->reg[0xca/2] & 0x0fff) - ax * dstep1; break; case 0x0200: dstep1 = -1; dstep2 = -1 * (hd63484->reg[0xca/2] & 0x0fff) + ax * dstep1; break; case 0x0300: dstep1 = -1; dstep2 = (hd63484->reg[0xca/2] & 0x0fff) + ax * dstep1; break; case 0x0400: dstep1 = -1 * (hd63484->reg[0xca/2] & 0x0fff); dstep2 = 1 - ay * dstep1; break; case 0x0500: dstep1 = (hd63484->reg[0xca/2] & 0x0fff); dstep2 = 1 - ay * dstep1; break; case 0x0600: dstep1 = -1 * (hd63484->reg[0xca/2] & 0x0fff); dstep2 = -1 + ay * dstep1; break; case 0x0700: dstep1 = (hd63484->reg[0xca/2] & 0x0fff); dstep2 = -1 + ay * dstep1; break; } for (;;) { for (;;) { switch (opcode & 0x0007) { case 0: hd63484->ram[*dst] = hd63484->ram[src]; break; case 1: hd63484->ram[*dst] |= hd63484->ram[src]; break; case 2: hd63484->ram[*dst] &= hd63484->ram[src]; break; case 3: hd63484->ram[*dst] ^= hd63484->ram[src]; break; case 4: if (hd63484->ram[*dst] == (hd63484->ccmp & 0xff)) hd63484->ram[*dst] = hd63484->ram[src]; break; case 5: if (hd63484->ram[*dst] != (hd63484->ccmp & 0xff)) hd63484->ram[*dst] = hd63484->ram[src]; break; case 6: if (hd63484->ram[*dst] < hd63484->ram[src]) hd63484->ram[*dst] = hd63484->ram[src]; break; case 7: if (hd63484->ram[*dst] > hd63484->ram[src]) hd63484->ram[*dst] = hd63484->ram[src]; break; } if (opcode & 0x0800) { if (ay == 0) break; if (_ay > 0) { src = (src - (hd63484->reg[0xca/2] & 0x0fff)) & (HD63484_RAM_SIZE - 1); *dst = (*dst + dstep1) & (HD63484_RAM_SIZE - 1); ay--; } else { src = (src + (hd63484->reg[0xca/2] & 0x0fff)) & (HD63484_RAM_SIZE - 1); *dst = (*dst + dstep1) & (HD63484_RAM_SIZE - 1); ay++; } } else { if (ax == 0) break; else if (ax > 0) { src = (src + 1) & (HD63484_RAM_SIZE - 1); *dst = (*dst + dstep1) & (HD63484_RAM_SIZE - 1); ax--; } else { src = (src - 1) & (HD63484_RAM_SIZE - 1); *dst = (*dst + dstep1) & (HD63484_RAM_SIZE - 1); ax++; } } } if (opcode & 0x0800) { ay = _ay; if (_ax < 0) { src = (src - 1 + ay * (hd63484->reg[0xca/2] & 0x0fff)) & (HD63484_RAM_SIZE - 1); *dst = (*dst + dstep2) & (HD63484_RAM_SIZE - 1); if (ax == 0) break; ax++; } else { src = (src + 1 - ay * (hd63484->reg[0xca/2] & 0x0fff)) & (HD63484_RAM_SIZE - 1); *dst = (*dst + dstep2) & (HD63484_RAM_SIZE - 1); if (ax == 0) break; ax--; } } else { ax = _ax; if (_ay < 0) { src = (src + (hd63484->reg[0xca/2] & 0x0fff) - ax) & (HD63484_RAM_SIZE - 1); *dst = (*dst + dstep2) & (HD63484_RAM_SIZE - 1); if (ay == 0) break; ay++; } else { src = (src - (hd63484->reg[0xca/2] & 0x0fff) - ax) & (HD63484_RAM_SIZE - 1); *dst = (*dst + dstep2) & (HD63484_RAM_SIZE - 1); if (ay == 0) break; ay--; } } } } static int org_first_pixel( device_t *device, int _org_dpd ) { hd63484_state *hd63484 = get_safe_token(device); int gbm = (hd63484->reg[0x02/2] & 0x700) >> 8; switch (gbm) { case 0: return (_org_dpd & 0x0f); case 1: return (_org_dpd & 0x0e) >> 1; case 2: return (_org_dpd & 0x0c) >> 2; case 3: return (_org_dpd & 0x08) >> 3; case 4: return 0; default: logerror ("Graphic bit mode not supported\n"); return 0; } } static void dot( device_t *device, int x, int y, int opm, UINT16 color ) { hd63484_state *hd63484 = get_safe_token(device); int dst, x_int, x_mod, bpp; UINT16 color_shifted, bitmask, bitmask_shifted; x += org_first_pixel(device, hd63484->org_dpd); switch ((hd63484->reg[0x02/2] & 0x700) >> 8) { case 0: bpp = 1; bitmask = 0x0001; break; case 1: bpp = 2; bitmask = 0x0003; break; case 2: bpp = 4; bitmask = 0x000f; break; case 3: bpp = 8; bitmask = 0x00ff; break; case 4: bpp = 16; bitmask = 0xffff; break; default: bpp = 0; bitmask = 0x0000; logerror ("Graphic bit mode not supported\n"); } // bpp = 4; // for skattva // bitmask = 0x000f; // for skattva if (x >= 0) { x_int = x / (16 / bpp); x_mod = x % (16 / bpp); } else { x_int = x / (16 / bpp); x_mod = -1 * (x % (16 / bpp)); if (x_mod) { x_int--; x_mod = (16 / bpp) - x_mod; } } color &= bitmask; bitmask_shifted = bitmask << (x_mod * bpp); color_shifted = color << (x_mod * bpp); dst = (hd63484->org + x_int - y * (hd63484->reg[0xca/2] & 0x0fff)) & (HD63484_RAM_SIZE - 1); switch (opm) { case 0: hd63484->ram[dst] = (hd63484->ram[dst] & ~bitmask_shifted) | color_shifted; break; case 1: hd63484->ram[dst] = hd63484->ram[dst] | color_shifted; break; case 2: hd63484->ram[dst] = hd63484->ram[dst] & ((hd63484->ram[dst] & ~bitmask_shifted) | color_shifted); break; case 3: hd63484->ram[dst] = hd63484->ram[dst] ^ color_shifted; break; case 4: if (get_pixel(device, x, y) == (hd63484->ccmp & bitmask)) hd63484->ram[dst] = (hd63484->ram[dst] & ~bitmask_shifted) | color_shifted; break; case 5: if (get_pixel(device, x, y) != (hd63484->ccmp & bitmask)) hd63484->ram[dst] = (hd63484->ram[dst] & ~bitmask_shifted) | color_shifted; break; case 6: if (get_pixel(device, x, y) < (hd63484->cl0 & bitmask)) hd63484->ram[dst] = (hd63484->ram[dst] & ~bitmask_shifted) | color_shifted; break; case 7: if (get_pixel(device, x, y) > (hd63484->cl0 & bitmask)) hd63484->ram[dst] = (hd63484->ram[dst] & ~bitmask_shifted) | color_shifted; break; } } static int get_pixel( device_t *device, int x, int y ) { hd63484_state *hd63484 = get_safe_token(device); int dst, x_int, x_mod, bpp; UINT16 bitmask, bitmask_shifted; switch ((hd63484->reg[0x02/2] & 0x700) >> 8) { case 0: bpp = 1; bitmask = 0x0001; break; case 1: bpp = 2; bitmask = 0x0003; break; case 2: bpp = 4; bitmask = 0x000f; break; case 3: bpp = 8; bitmask = 0x00ff; break; case 4: bpp = 16; bitmask = 0xffff; break; default: bpp = 0; bitmask = 0x0000; logerror ("Graphic bit mode not supported\n"); } if (x >= 0) { x_int = x / (16 / bpp); x_mod = x % (16 / bpp); } else { x_int = x / (16 / bpp); x_mod = -1 * (x % (16 / bpp)); if (x_mod) { x_int--; x_mod = (16 / bpp) - x_mod; } } bitmask_shifted = bitmask << (x_mod * bpp); dst = (hd63484->org + x_int - y * (hd63484->reg[0xca/2] & 0x0fff)) & (HD63484_RAM_SIZE - 1); return ((hd63484->ram[dst] & bitmask_shifted) >> (x_mod * bpp)); } static int get_pixel_ptn( device_t *device, int x, int y ) { hd63484_state *hd63484 = get_safe_token(device); int dst, x_int, x_mod, bpp; UINT16 bitmask, bitmask_shifted; bpp = 1; bitmask = 0x0001; if (x >= 0) { x_int = x / (16 / bpp); x_mod = x % (16 / bpp); } else { x_int = x / (16 / bpp); x_mod = -1 * (x % (16 / bpp)); if (x_mod) { x_int--; x_mod = (16 / bpp) - x_mod; } } bitmask_shifted = bitmask << (x_mod * bpp); dst = (x_int + y * 1); if ((hd63484->pattern[dst] & bitmask_shifted) >> (x_mod * bpp)) return 1; else return 0; } static void agcpy( device_t *device, int opcode, int src_x, int src_y, int dst_x, int dst_y, INT16 _ax, INT16 _ay ) { int dst_step1_x,dst_step1_y,dst_step2_x,dst_step2_y; int src_step1_x,src_step1_y,src_step2_x,src_step2_y; int ax_neg,ay_neg; int ax = _ax; int ay = _ay; int xxs = src_x; int yys = src_y; int xxd = dst_x; int yyd = dst_y; if (ax < 0) ax_neg = -1; else ax_neg = 1; if (ay < 0) ay_neg = -1; else ay_neg = 1; if (opcode & 0x0800) switch (opcode & 0x0700) { default: case 0x0000: dst_step1_x = 1; dst_step1_y = 0; dst_step2_x = -ay_neg*ay; dst_step2_y = 1; break; case 0x0100: dst_step1_x = 1; dst_step1_y = 0; dst_step2_x = -ay_neg*ay; dst_step2_y = -1; break; case 0x0200: dst_step1_x = -1; dst_step1_y = 0; dst_step2_x = ay_neg*ay; dst_step2_y = 1; break; case 0x0300: dst_step1_x = -1; dst_step1_y = 0; dst_step2_x = ay_neg*ay; dst_step2_y = -1; break; case 0x0400: dst_step1_x = 0; dst_step1_y = 1; dst_step2_x = 1; dst_step2_y = -ay_neg*ay; break; case 0x0500: dst_step1_x = 0; dst_step1_y = -1; dst_step2_x = 1; dst_step2_y = ay_neg*ay; break; case 0x0600: dst_step1_x = 0; dst_step1_y = 1; dst_step2_x = -1; dst_step2_y = -ay_neg*ay; break; case 0x0700: dst_step1_x = 0; dst_step1_y = -1; dst_step2_x = -1; dst_step2_y = ay_neg*ay; break; } else switch (opcode & 0x0700) { default: case 0x0000: dst_step1_x = 1; dst_step1_y = 0; dst_step2_x = -ax_neg*ax; dst_step2_y = 1; break; case 0x0100: dst_step1_x = 1; dst_step1_y = 0; dst_step2_x = -ax_neg*ax; dst_step2_y = -1; break; case 0x0200: dst_step1_x = -1; dst_step1_y = 0; dst_step2_x = ax_neg*ax; dst_step2_y = 1; break; case 0x0300: dst_step1_x = -1; dst_step1_y = 0; dst_step2_x = ax_neg*ax; dst_step2_y = -1; break; case 0x0400: dst_step1_x = 0; dst_step1_y = 1; dst_step2_x = 1; dst_step2_y = ax_neg*ax; break; case 0x0500: dst_step1_x = 0; dst_step1_y = -1; dst_step2_x = 1; dst_step2_y = -ax_neg*ax; break; case 0x0600: dst_step1_x = 0; dst_step1_y = 1; dst_step2_x = -1; dst_step2_y = ax_neg*ax; break; case 0x0700: dst_step1_x = 0; dst_step1_y = -1; dst_step2_x = -1; dst_step2_y = -ax_neg*ax; break; } if ((_ax >= 0) && (_ay >= 0) && ((opcode & 0x0800) == 0x0000)) { src_step1_x = 1; src_step1_y = 0; src_step2_x = -ax; src_step2_y = 1; } else if ((_ax >= 0) && (_ay < 0) && ((opcode & 0x0800) == 0x0000)) { src_step1_x = 1; src_step1_y = 0; src_step2_x = -ax; src_step2_y = -1; } else if ((_ax < 0) && (_ay >= 0) && ((opcode & 0x0800) == 0x0000)) { src_step1_x = -1; src_step1_y = 0; src_step2_x = -ax; src_step2_y = 1; } else if ((_ax < 0) && (_ay < 0) && ((opcode & 0x0800) == 0x0000)) { src_step1_x = -1; src_step1_y = 0; src_step2_x = -ax; src_step2_y = -1; } else if ((_ax >= 0) && (_ay >= 0) && ((opcode & 0x0800) == 0x0800)) { src_step1_x = 0; src_step1_y = 1; src_step2_x = 1; src_step2_y = -ay; } else if ((_ax >= 0) && (_ay < 0) && ((opcode & 0x0800) == 0x0800)) { src_step1_x = 0; src_step1_y = -1; src_step2_x = 1; src_step2_y = -ay; } else if ((_ax < 0) && (_ay >= 0) && ((opcode & 0x0800) == 0x0800)) { src_step1_x = 0; src_step1_y = 1; src_step2_x = -1; src_step2_y = -ay; } else // ((_ax < 0) && (_ay < 0) && ((opcode & 0x0800) == 0x0800)) { src_step1_x = 0; src_step1_y = -1; src_step2_x = -1; src_step2_y = -ay; } for (;;) { for (;;) { dot(device, xxd, yyd, opcode & 0x0007, get_pixel(device, xxs, yys)); if (opcode & 0x0800) { if (ay == 0) break; if (_ay > 0) { xxs += src_step1_x; yys += src_step1_y; xxd += dst_step1_x; yyd += dst_step1_y; ay--; } else { xxs += src_step1_x; yys += src_step1_y; xxd += dst_step1_x; yyd += dst_step1_y; ay++; } } else { if (ax == 0) break; else if (ax > 0) { xxs += src_step1_x; yys += src_step1_y; xxd += dst_step1_x; yyd += dst_step1_y; ax--; } else { xxs += src_step1_x; yys += src_step1_y; xxd += dst_step1_x; yyd += dst_step1_y; ax++; } } } if (opcode & 0x0800) { ay = _ay; if (_ax < 0) { xxs += src_step2_x; yys += src_step2_y; xxd += dst_step2_x; yyd += dst_step2_y; if (ax == 0) break; ax++; } else { xxs += src_step2_x; yys += src_step2_y; xxd += dst_step2_x; yyd += dst_step2_y; if (ax == 0) break; ax--; } } else { ax = _ax; if (_ay < 0) { xxs += src_step2_x; yys += src_step2_y; xxd += dst_step2_x; yyd += dst_step2_y; if (ay == 0) break; ay++; } else { xxs += src_step2_x; yys += src_step2_y; xxd += dst_step2_x; yyd += dst_step2_y; if (ay == 0) break; ay--; } } } } static void ptn( device_t *device, int opcode, int src_x, int src_y, INT16 _ax, INT16 _ay ) { hd63484_state *hd63484 = get_safe_token(device); int dst_step1_x = 0,dst_step1_y = 0,dst_step2_x = 0,dst_step2_y = 0; int src_step1_x,src_step1_y,src_step2_x,src_step2_y; int ax = _ax; int ay = _ay; int ax_neg; //,ay_neg; int xxs = src_x; int yys = src_y; int xxd = hd63484->cpx; int yyd = hd63484->cpy; int getpixel; if (ax < 0) ax_neg = -1; else ax_neg = 1; /* if (ay < 0) ay_neg = -1; else ay_neg = 1;*/ if (opcode & 0x0800) switch (opcode & 0x0700) { default: case 0x0000: logerror("PTN: not supported"); break; case 0x0100: logerror("PTN: not supported"); break; case 0x0200: logerror("PTN: not supported"); break; case 0x0300: logerror("PTN: not supported"); break; case 0x0400: logerror("PTN: not supported"); break; case 0x0500: logerror("PTN: not supported"); break; case 0x0600: logerror("PTN: not supported"); break; case 0x0700: logerror("PTN: not supported"); break; } else switch (opcode & 0x0700) { default: case 0x0000: dst_step1_x = 1; dst_step1_y = 0; dst_step2_x = -ax_neg*ax; dst_step2_y = 1; break; case 0x0100: logerror("PTN: not supported"); break; case 0x0200: dst_step1_x = 0; dst_step1_y = 1; dst_step2_x = -1; dst_step2_y = -ax_neg*ax; break; case 0x0300: logerror("PTN: not supported"); break; case 0x0400: dst_step1_x = -1; dst_step1_y = 0; dst_step2_x = ax_neg*ax; dst_step2_y = -1; break; case 0x0500: logerror("PTN: not supported"); break; case 0x0600: dst_step1_x = 0; dst_step1_y = -1; dst_step2_x = 1; dst_step2_y = ax_neg*ax; break; case 0x0700: logerror("PTN: not supported"); break; } src_step1_x = 1; src_step1_y = 0; src_step2_x = -ax; src_step2_y = 1; for (;;) { for (;;) { getpixel = get_pixel_ptn(device, xxs, yys); switch ((opcode & 0x0018) >> 3) { case 0x0000: if (getpixel) dot(device, xxd, yyd, opcode & 0x0007, hd63484->cl1); else dot(device, xxd, yyd, opcode & 0x0007, hd63484->cl0); break; case 0x0001: if (getpixel) dot(device, xxd, yyd, opcode & 0x0007, hd63484->cl1); break; case 0x0002: if (getpixel == 0) dot(device, xxd, yyd, opcode & 0x0007, hd63484->cl0); break; case 0x0003: logerror("PTN: not supported"); break; break; } if (opcode & 0x0800) { if (ay == 0) break; if (_ay > 0) { xxs += src_step1_x; yys += src_step1_y; xxd += dst_step1_x; yyd += dst_step1_y; ay--; } else { xxs += src_step1_x; yys += src_step1_y; xxd += dst_step1_x; yyd += dst_step1_y; ay++; } } else { if (ax == 0) break; else if (ax > 0) { xxs += src_step1_x; yys += src_step1_y; xxd += dst_step1_x; yyd += dst_step1_y; ax--; } else { xxs += src_step1_x; yys += src_step1_y; xxd += dst_step1_x; yyd += dst_step1_y; ax++; } } } if (opcode & 0x0800) { ay = _ay; if (_ax < 0) { xxs += src_step2_x; yys += src_step2_y; xxd += dst_step2_x; yyd += dst_step2_y; if (ax == 0) break; ax++; } else { xxs += src_step2_x; yys += src_step2_y; xxd += dst_step2_x; yyd += dst_step2_y; if (ax == 0) break; ax--; } } else { ax = _ax; if (_ay < 0) { xxs += src_step2_x; yys += src_step2_y; xxd += dst_step2_x; yyd += dst_step2_y; if (ay == 0) break; ay++; } else { xxs += src_step2_x; yys += src_step2_y; xxd += dst_step2_x; yyd += dst_step2_y; if (ay == 0) break; ay--; } } } } static void line( device_t *device, INT16 sx, INT16 sy, INT16 ex, INT16 ey, INT16 col ) { hd63484_state *hd63484 = get_safe_token(device); INT16 ax,ay; int cpx_t = sx; int cpy_t = sy; ax = ex - sx; ay = ey - sy; if (abs(ax) >= abs(ay)) { while (ax) { dot(device, cpx_t, cpy_t, col & 7, hd63484->cl0); if (ax > 0) { cpx_t++; ax--; } else { cpx_t--; ax++; } cpy_t = sy + ay * (cpx_t - sx) / (ex - sx); } } else { while (ay) { dot(device, cpx_t, cpy_t, col & 7, hd63484->cl0); if (ay > 0) { cpy_t++; ay--; } else { cpy_t--; ay++; } cpx_t = sx + ax * (cpy_t - sy) / (ey - sy); } } } static void circle( device_t *device, INT16 sx, INT16 sy, UINT16 r, INT16 col ) { const float DEG2RAD = 3.14159f/180; hd63484_state *hd63484 = get_safe_token(device); int i; for (i = 0; i < 360 * (r / 10); i++) { float degInRad = i * DEG2RAD / (r / 10); dot(device, sx + cos(degInRad) * r,sy + sin(degInRad) * r, col & 7, hd63484->cl0); } } static void paint( device_t *device, int sx, int sy, int col ) { hd63484_state *hd63484 = get_safe_token(device); int getpixel; dot(device, sx, sy, 0, col); getpixel = get_pixel(device, sx+1,sy); switch ((hd63484->reg[0x02/2] & 0x700) >> 8) { case 0: break; case 1: break; case 2: getpixel = (getpixel << 12) | (getpixel << 8) | (getpixel << 4) | (getpixel << 0); break; case 3: getpixel = (getpixel << 8) | (getpixel << 0); break; case 4: break; default: logerror ("Graphic bit mode not supported\n"); } if ((getpixel != col) && (getpixel != hd63484->edg)) { sx++; paint(device, sx, sy, col); sx--; } getpixel = get_pixel(device, sx - 1, sy); switch ((hd63484->reg[0x02/2] & 0x700) >> 8) { case 0: break; case 1: break; case 2: getpixel = (getpixel << 12) | (getpixel << 8) | (getpixel << 4) | (getpixel << 0); break; case 3: getpixel = (getpixel << 8) | (getpixel << 0); break; case 4: break; default: logerror ("Graphic bit mode not supported\n"); } if ((getpixel != col) && (getpixel != hd63484->edg)) { sx--; paint(device, sx, sy, col); sx++; } getpixel = get_pixel(device, sx, sy + 1); switch ((hd63484->reg[0x02/2] & 0x700) >> 8) { case 0: break; case 1: break; case 2: getpixel = (getpixel << 12) | (getpixel << 8) | (getpixel << 4) | (getpixel << 0); break; case 3: getpixel = (getpixel << 8) | (getpixel << 0); break; case 4: break; default: logerror ("Graphic bit mode not supported\n"); } if ((getpixel != col) && (getpixel != hd63484->edg)) { sy++; paint(device, sx, sy, col); sy--; } getpixel = get_pixel(device, sx, sy - 1); switch ((hd63484->reg[0x02/2] & 0x700) >> 8) { case 0: break; case 1: break; case 2: getpixel = (getpixel << 12) | (getpixel << 8) | (getpixel << 4) | (getpixel << 0); break; case 3: getpixel = (getpixel << 8) | (getpixel << 0); break; case 4: break; default: logerror ("Graphic bit mode not supported\n"); } if ((getpixel != col) && (getpixel != hd63484->edg)) { sy--; paint(device, sx, sy, col); sy++; } } static void hd63484_command_w(device_t *device, UINT16 cmd) { hd63484_state *hd63484 = get_safe_token(device); int len; hd63484->fifo[hd63484->fifo_counter++] = cmd; len = instruction_length[hd63484->fifo[0] >> 10]; if (len == -1) { if (hd63484->fifo_counter < 2) return; else len = hd63484->fifo[1] + 2; } else if (len == -2) { if (hd63484->fifo_counter < 2) return; else len = 2 * hd63484->fifo[1] + 2; } if (hd63484->fifo_counter >= len) { #if LOG_COMMANDS int i; logerror("%s: HD63484 command %s (%04x) ", device->machine().describe_context(), instruction_name[hd63484->fifo[0] >> 10], hd63484->fifo[0]); for (i = 1; i < hd63484->fifo_counter; i++) logerror("%04x ", hd63484->fifo[i]); logerror("\n"); #endif if (hd63484->fifo[0] == 0x0400) { /* ORG */ hd63484->org = ((hd63484->fifo[1] & 0x00ff) << 12) | ((hd63484->fifo[2] & 0xfff0) >> 4); hd63484->org_dpd = hd63484->fifo[2] & 0x000f; } else if ((hd63484->fifo[0] & 0xffe0) == 0x0800) /* WPR */ { if (hd63484->fifo[0] == 0x0800) hd63484->cl0 = hd63484->fifo[1]; else if (hd63484->fifo[0] == 0x0801) hd63484->cl1 = hd63484->fifo[1]; else if (hd63484->fifo[0] == 0x0802) hd63484->ccmp = hd63484->fifo[1]; else if (hd63484->fifo[0] == 0x0803) hd63484->edg = hd63484->fifo[1]; else if (hd63484->fifo[0] == 0x0804) hd63484->mask = hd63484->fifo[1]; else if (hd63484->fifo[0] == 0x0805) { hd63484->ppy = (hd63484->fifo[1] & 0xf000) >> 12; hd63484->pzcy = (hd63484->fifo[1] & 0x0f00) >> 8; hd63484->ppx = (hd63484->fifo[1] & 0x00f0) >> 4; hd63484->pzcx = (hd63484->fifo[1] & 0x000f) >> 0; } else if (hd63484->fifo[0] == 0x0806) { hd63484->psy = (hd63484->fifo[1] & 0xf000) >> 12; hd63484->psx = (hd63484->fifo[1] & 0x00f0) >> 4; } else if (hd63484->fifo[0] == 0x0807) { hd63484->pey = (hd63484->fifo[1] & 0xf000) >> 12; hd63484->pzy = (hd63484->fifo[1] & 0x0f00) >> 8; hd63484->pex = (hd63484->fifo[1] & 0x00f0) >> 4; hd63484->pzx = (hd63484->fifo[1] & 0x000f) >> 0; } else if (hd63484->fifo[0] == 0x0808) hd63484->xmin = hd63484->fifo[1]; else if (hd63484->fifo[0] == 0x0809) hd63484->ymin = hd63484->fifo[1]; else if (hd63484->fifo[0] == 0x080a) hd63484->xmax = hd63484->fifo[1]; else if (hd63484->fifo[0] == 0x080b) hd63484->ymax = hd63484->fifo[1]; else if (hd63484->fifo[0] == 0x080c) { hd63484->rwp = (hd63484->rwp & 0x00fff) | ((hd63484->fifo[1] & 0x00ff) << 12); hd63484->rwp_dn = (hd63484->fifo[1] & 0xc000) >> 14; } else if (hd63484->fifo[0] == 0x080d) { hd63484->rwp = (hd63484->rwp & 0xff000) | ((hd63484->fifo[1] & 0xfff0) >> 4); } else logerror("unsupported register\n"); } else if ((hd63484->fifo[0] & 0xffe0) == 0x0c00) /* RPR */ { if (hd63484->fifo[0] == 0x0c00) hd63484->fifo[1] = hd63484->cl0; else if (hd63484->fifo[0] == 0x0c01) hd63484->fifo[1] = hd63484->cl1; else if (hd63484->fifo[0] == 0x0c02) hd63484->fifo[1] = hd63484->ccmp; else if (hd63484->fifo[0] == 0x0c03) hd63484->fifo[1] = hd63484->edg; else if (hd63484->fifo[0] == 0x0c04) hd63484->fifo[1] = hd63484->mask; else if (hd63484->fifo[0] == 0x0c05) { hd63484->fifo[1] = (hd63484->ppy << 12) | (hd63484->pzcy << 8) | (hd63484->ppx << 4) | hd63484->pzcx; } else if (hd63484->fifo[0] == 0x0c06) { hd63484->fifo[1] = (hd63484->psx << 12) | (hd63484->psx << 4); } else if (hd63484->fifo[0] == 0x0c07) { hd63484->fifo[1] = (hd63484->pey << 12) | (hd63484->pzy << 8) | (hd63484->pex << 4) | hd63484->pzx; } else if (hd63484->fifo[0] == 0x0c08) hd63484->fifo[1] = hd63484->xmin; else if (hd63484->fifo[0] == 0x0c09) hd63484->fifo[1] = hd63484->ymin; else if (hd63484->fifo[0] == 0x0c0a) hd63484->fifo[1] = hd63484->xmax; else if (hd63484->fifo[0] == 0x0c0b) hd63484->fifo[1] = hd63484->ymax; else if (hd63484->fifo[0] == 0x0c0c) { hd63484->fifo[1] = (hd63484->rwp_dn << 14) | ((hd63484->rwp >> 12) & 0xff); } else if (hd63484->fifo[0] == 0x0c0d) { hd63484->fifo[1] = (hd63484->rwp & 0x0fff) << 4; } else if (hd63484->fifo[0] == 0x0c10) { // TODO } else if (hd63484->fifo[0] == 0x0c11) { // TODO } else if (hd63484->fifo[0] == 0x0c12) { hd63484->fifo[1] = hd63484->cpx; } else if (hd63484->fifo[0] == 0x0c13) { hd63484->fifo[1] = hd63484->cpy; } else logerror("unsupported register\n"); } else if ((hd63484->fifo[0] & 0xfff0) == 0x1800) /* WPTN */ { int i; int start = hd63484->fifo[0] & 0x000f; int n = hd63484->fifo[1]; for (i = 0; i < n; i++) hd63484->pattern[start + i] = hd63484->fifo[2 + i]; } else if (hd63484->fifo[0] == 0x4400) /* RD */ { hd63484->readfifo = hd63484->ram[hd63484->rwp]; hd63484->rwp = (hd63484->rwp + 1) & (HD63484_RAM_SIZE - 1); } else if (hd63484->fifo[0] == 0x4800) /* WT */ { hd63484->ram[hd63484->rwp] = hd63484->fifo[1]; hd63484->rwp = (hd63484->rwp + 1) & (HD63484_RAM_SIZE - 1); } else if (hd63484->fifo[0] == 0x5800) /* CLR */ { doclr16(device, hd63484->fifo[0], hd63484->fifo[1], &hd63484->rwp, hd63484->fifo[2], hd63484->fifo[3]); { int fifo2 = (int)hd63484->fifo[2], fifo3 = (int)hd63484->fifo[3]; if (fifo2 < 0) fifo2 *= -1; if (fifo3 < 0) fifo3 *= -1; hd63484->rwp += ((fifo2 + 1) * (fifo3 + 1)); } } else if ((hd63484->fifo[0] & 0xfffc) == 0x5c00) /* SCLR */ { doclr16(device, hd63484->fifo[0], hd63484->fifo[1], &hd63484->rwp, hd63484->fifo[2], hd63484->fifo[3]); { int fifo2 = (int)hd63484->fifo[2], fifo3 = (int)hd63484->fifo[3]; if (fifo2 < 0) fifo2 *= -1; if (fifo3 < 0) fifo3 *= -1; hd63484->rwp += ((fifo2 + 1) * (fifo3 + 1)); } } else if ((hd63484->fifo[0] & 0xf0ff) == 0x6000) /* hd63484->cpy */ { docpy16(device, hd63484->fifo[0], ((hd63484->fifo[1] & 0x00ff) << 12) | ((hd63484->fifo[2] & 0xfff0) >> 4), &hd63484->rwp, hd63484->fifo[3], hd63484->fifo[4]); { int fifo2 = (int)hd63484->fifo[2], fifo3 = (int)hd63484->fifo[3]; if (fifo2 < 0) fifo2 *= -1; if (fifo3 < 0) fifo3 *= -1; hd63484->rwp += ((fifo2 + 1) * (fifo3 + 1)); } } else if ((hd63484->fifo[0] & 0xf0fc) == 0x7000) /* Shd63484->cpy */ { docpy16(device, hd63484->fifo[0], ((hd63484->fifo[1] & 0x00ff) << 12) | ((hd63484->fifo[2] & 0xfff0) >> 4), &hd63484->rwp, hd63484->fifo[3], hd63484->fifo[4]); { int fifo2 = (int)hd63484->fifo[2], fifo3 = (int)hd63484->fifo[3]; if (fifo2 < 0) fifo2 *= -1; if (fifo3 < 0) fifo3 *= -1; hd63484->rwp += ((fifo2 + 1) * (fifo3 + 1)); } } else if (hd63484->fifo[0] == 0x8000) /* AMOVE */ { hd63484->cpx = hd63484->fifo[1]; hd63484->cpy = hd63484->fifo[2]; } else if (hd63484->fifo[0] == 0x8400) /* RMOVE */ { hd63484->cpx += (INT16)hd63484->fifo[1]; hd63484->cpy += (INT16)hd63484->fifo[2]; } else if ((hd63484->fifo[0] & 0xff00) == 0x8800) /* ALINE */ { line(device, hd63484->cpx, hd63484->cpy, hd63484->fifo[1], hd63484->fifo[2], hd63484->fifo[0] & 0xff); hd63484->cpx = (INT16)hd63484->fifo[1]; hd63484->cpy = (INT16)hd63484->fifo[2]; } else if ((hd63484->fifo[0] & 0xff00) == 0x8c00) /* RLINE */ { line(device, hd63484->cpx, hd63484->cpy, hd63484->cpx + (INT16)hd63484->fifo[1], hd63484->cpy + (INT16)hd63484->fifo[2], hd63484->fifo[0] & 0xff); hd63484->cpx += (INT16)hd63484->fifo[1]; hd63484->cpy += (INT16)hd63484->fifo[2]; } else if ((hd63484->fifo[0] & 0xfff8) == 0x9000) /* ARCT */ { line(device, hd63484->cpx, hd63484->cpy, (INT16)hd63484->fifo[1], hd63484->cpy, hd63484->fifo[0] & 0xff); line(device, (INT16)hd63484->fifo[1], hd63484->cpy, (INT16)hd63484->fifo[1], (INT16)hd63484->fifo[2], hd63484->fifo[0] & 0xff); line(device, (INT16)hd63484->fifo[1], (INT16)hd63484->fifo[2], hd63484->cpx, (INT16)hd63484->fifo[2], hd63484->fifo[0] & 0xff); line(device, hd63484->cpx, (INT16)hd63484->fifo[2], hd63484->cpx, hd63484->cpy, hd63484->fifo[0] & 0xff); hd63484->cpx = (INT16)hd63484->fifo[1]; hd63484->cpy = (INT16)hd63484->fifo[2]; } else if ((hd63484->fifo[0] & 0xfff8) == 0x9400) /* RRCT added*/ { line(device, hd63484->cpx, hd63484->cpy, hd63484->cpx + (INT16)hd63484->fifo[1], hd63484->cpy, hd63484->fifo[0] & 0xff); line(device, hd63484->cpx + (INT16)hd63484->fifo[1], hd63484->cpy, hd63484->cpx + (INT16)hd63484->fifo[1], hd63484->cpy + (INT16)hd63484->fifo[2], hd63484->fifo[0] & 0xff); line(device, hd63484->cpx + (INT16)hd63484->fifo[1], hd63484->cpy + (INT16)hd63484->fifo[2], hd63484->cpx, hd63484->cpy + (INT16)hd63484->fifo[2], hd63484->fifo[0] & 0xff); line(device, hd63484->cpx, hd63484->cpy + (INT16)hd63484->fifo[2], hd63484->cpx, hd63484->cpy, hd63484->fifo[0] & 0xff); hd63484->cpx += (INT16)hd63484->fifo[1]; hd63484->cpy += (INT16)hd63484->fifo[2]; } else if ((hd63484->fifo[0] & 0xfff8) == 0xa400) /* RPLG added*/ { int nseg, sx, sy, ex, ey; sx = hd63484->cpx; sy = hd63484->cpy; for (nseg = 0; nseg < hd63484->fifo[1]; nseg++) { ex = sx + (INT16)hd63484->fifo[2 + nseg * 2]; ey = sy + (INT16)hd63484->fifo[2 + nseg * 2 + 1]; line(device, sx, sy, ex, ey, hd63484->fifo[0] & 7); sx = ex; sy = ey; } line(device, sx, sy, hd63484->cpx, hd63484->cpy, hd63484->fifo[0] & 7); } else if ((hd63484->fifo[0] & 0xfe00) == 0xa800) /* CRCL added*/ { circle(device, hd63484->cpx, hd63484->cpy, hd63484->fifo[1] & 0x1fff, hd63484->fifo[0] & 7); // only 13 bit are used for the radius } else if ((hd63484->fifo[0] & 0xfff8) == 0xc000) /* AFRCT */ { INT16 pcx, pcy; INT16 ax, ay, xx, yy; pcx = hd63484->fifo[1]; pcy = hd63484->fifo[2]; ax = pcx - hd63484->cpx; ay = pcy - hd63484->cpy; xx = hd63484->cpx; yy = hd63484->cpy; for (;;) { for (;;) { dot(device, xx, yy, hd63484->fifo[0] & 0x07, hd63484->cl0); if (ax == 0) break; else if (ax > 0) { xx++; ax--; } else { xx--; ax++; } } ax = pcx - hd63484->cpx; if (pcy < hd63484->cpy) { yy--; xx -= ax; if (ay == 0) break; ay++; } else { yy++; xx -= ax; if (ay == 0) break; ay--; } } } else if ((hd63484->fifo[0] & 0xfff8) == 0xc400) /* RFRCT added TODO*/ { line(device, hd63484->cpx, hd63484->cpy, hd63484->cpx + (INT16)hd63484->fifo[1], hd63484->cpy, hd63484->fifo[0] & 0xff); line(device, hd63484->cpx + hd63484->fifo[1], hd63484->cpy, hd63484->cpx + hd63484->fifo[1], hd63484->cpy + hd63484->fifo[2], hd63484->fifo[0] & 0xff); line(device, hd63484->cpx + hd63484->fifo[1], hd63484->cpy + hd63484->fifo[2], hd63484->cpx, hd63484->cpy + hd63484->fifo[2], hd63484->fifo[0] & 0xff); line(device, hd63484->cpx, hd63484->cpy + hd63484->fifo[2], hd63484->cpx, hd63484->cpy, hd63484->fifo[0] & 0xff); hd63484->cpx = hd63484->cpx + (INT16)hd63484->fifo[1]; hd63484->cpy = hd63484->cpy + (INT16)hd63484->fifo[2]; } else if (hd63484->fifo[0] == 0xc800) /* PAINT */ { paint(device, hd63484->cpx, hd63484->cpy, hd63484->cl0); } else if ((hd63484->fifo[0] & 0xfff8) == 0xcc00) /* DOT */ { dot(device, hd63484->cpx, hd63484->cpy, hd63484->fifo[0] & 0xff, hd63484->cl0); } else if ((hd63484->fifo[0] & 0xf000) == 0xd000) /* PTN (to do) */ { ptn(device, hd63484->fifo[0], hd63484->psx, hd63484->psy, hd63484->pex - hd63484->psx, hd63484->pey - hd63484->psy); if ((hd63484->fifo[0] & 0x0800) == 0x0000) switch (hd63484->fifo[0] & 0x0700) { case 0x0000: if ((hd63484->pey - hd63484->psy) > 0) hd63484->cpy += (hd63484->pey - hd63484->psy); else hd63484->cpy -= (hd63484->pey - hd63484->psy); break; case 0x0100: // missing break; case 0x0200: if ((hd63484->pey - hd63484->psy) > 0) hd63484->cpx += (hd63484->pey - hd63484->psy); else hd63484->cpx -= (hd63484->pey - hd63484->psy); break; case 0x0300: // missing break; case 0x0400: if ((hd63484->pey - hd63484->psy) > 0) hd63484->cpy -= (hd63484->pey - hd63484->psy); else hd63484->cpy += (hd63484->pey - hd63484->psy); break; case 0x0500: // missing break; case 0x0600: if ((hd63484->pey - hd63484->psy) > 0) hd63484->cpx -= (hd63484->pey - hd63484->psy); else hd63484->cpx += (hd63484->pey - hd63484->psy); break; case 0x0700: // missing break; } else { // missing } } else if ((hd63484->fifo[0] & 0xf018) == 0xe000) /* agcpy */ { agcpy(device, hd63484->fifo[0], (INT16)hd63484->fifo[1], (INT16)hd63484->fifo[2], hd63484->cpx, hd63484->cpy, hd63484->fifo[3], hd63484->fifo[4]); switch (hd63484->fifo[0] & 0x0700) { case 0x0000: if (hd63484->fifo[4] > 0) hd63484->cpy += hd63484->fifo[4]; else hd63484->cpy -= hd63484->fifo[4]; break; case 0x0100: if (hd63484->fifo[4] > 0) hd63484->cpy -= hd63484->fifo[4]; else hd63484->cpy += hd63484->fifo[4]; break; case 0x0200: if (hd63484->fifo[4] > 0) hd63484->cpy += hd63484->fifo[4]; else hd63484->cpy -= hd63484->fifo[4]; break; case 0x0300: if (hd63484->fifo[4] > 0) hd63484->cpy -= hd63484->fifo[4]; else hd63484->cpy += hd63484->fifo[4]; break; case 0x0400: if (hd63484->fifo[3] > 0) hd63484->cpx += hd63484->fifo[3]; else hd63484->cpx -= hd63484->fifo[3]; break; case 0x0500: if (hd63484->fifo[3] > 0) hd63484->cpx += hd63484->fifo[3]; else hd63484->cpx -= hd63484->fifo[3]; break; case 0x0600: if (hd63484->fifo[3] > 0) hd63484->cpx -= hd63484->fifo[3]; else hd63484->cpx += hd63484->fifo[3]; break; case 0x0700: if (hd63484->fifo[3] > 0) hd63484->cpx -= hd63484->fifo[3]; else hd63484->cpx += hd63484->fifo[3]; break; } } else { logerror("unsupported command\n"); popmessage("unsupported command %s (%04x)", instruction_name[hd63484->fifo[0] >> 10], hd63484->fifo[0]); } hd63484->fifo_counter = 0; } } READ16_DEVICE_HANDLER( hd63484_status_r ) { // if (cpu_get_pc(&space->device()) != 0xfced6 && cpu_get_pc(&space->device()) != 0xfe1d6) // logerror("%05x: HD63484 status read\n",cpu_get_pc(&space->device())); return 0xff22 | (device->machine().rand() & 0x0004); /* write FIFO ready + command end + (read FIFO ready or read FIFO not ready) */ } WRITE16_DEVICE_HANDLER( hd63484_address_w ) { hd63484_state *hd63484 = get_safe_token(device); /* only low 8 bits are used */ if (ACCESSING_BITS_0_7) hd63484->regno = data; } WRITE16_DEVICE_HANDLER( hd63484_data_w ) { hd63484_state *hd63484 = get_safe_token(device); COMBINE_DATA(&hd63484->reg[hd63484->regno/2]); if (hd63484->skattva_hack) hd63484->reg[2/2] = (hd63484->reg[2/2] & 0xf8ff) | 0x0200; // hack to set proper color depth in skattva if (hd63484->regno & 0x80) hd63484->regno += 2; /* autoincrement */ #if LOG_COMMANDS // logerror("PC %05x: HD63484 register %02x write %04x\n", cpu_get_pc(&space->device()), hd63484->regno, hd63484->reg[hd63484->regno/2]); #endif if (hd63484->regno == 0) /* FIFO */ hd63484_command_w(device, hd63484->reg[0]); } READ16_DEVICE_HANDLER( hd63484_data_r ) { hd63484_state *hd63484 = get_safe_token(device); int res; if (hd63484->regno == 0x80) res = device->machine().primary_screen->vpos(); else if (hd63484->regno == 0) { #if LOG_COMMANDS // logerror("%05x: HD63484 read FIFO\n", cpu_get_pc(&space->device())); #endif res = hd63484->readfifo; } else { #if LOG_COMMANDS // logerror("%05x: HD63484 read register %02x\n", cpu_get_pc(&space->device()), hd63484->regno); #endif res = 0; } return res; } READ16_DEVICE_HANDLER( hd63484_ram_r ) { hd63484_state *hd63484 = get_safe_token(device); return hd63484->ram[offset]; } READ16_DEVICE_HANDLER( hd63484_regs_r ) { hd63484_state *hd63484 = get_safe_token(device); return hd63484->reg[offset]; } WRITE16_DEVICE_HANDLER( hd63484_ram_w ) { hd63484_state *hd63484 = get_safe_token(device); COMBINE_DATA(&hd63484->ram[offset]); } WRITE16_DEVICE_HANDLER( hd63484_regs_w ) { hd63484_state *hd63484 = get_safe_token(device); COMBINE_DATA(&hd63484->reg[offset]); } static DEVICE_START( hd63484 ) { hd63484_state *hd63484 = get_safe_token(device); const hd63484_interface *intf = get_interface(device); hd63484->skattva_hack = intf->skattva_hack; hd63484->ram = auto_alloc_array_clear(device->machine(), UINT16, HD63484_RAM_SIZE); // device->save_item(NAME(hd63484->clear_bitmap)); // device->save_pointer(NAME(hd63484->spriteram), 0x1000); // device->save_item(NAME(*hd63484->sprites_bitmap)); } static DEVICE_RESET( hd63484 ) { hd63484_state *hd63484 = get_safe_token(device); hd63484->fifo_counter = 0; } static const char DEVTEMPLATE_SOURCE[] = __FILE__; #define DEVTEMPLATE_ID( p, s ) p##hd63484##s #define DEVTEMPLATE_FEATURES DT_HAS_START | DT_HAS_RESET #define DEVTEMPLATE_NAME "HD63484" #define DEVTEMPLATE_FAMILY "HD63484 Video Controller" #include "devtempl.h" DEFINE_LEGACY_DEVICE(HD63484, hd63484);