diff --git a/.gitattributes b/.gitattributes index 37d27268163..fc2a8d01c02 100644 --- a/.gitattributes +++ b/.gitattributes @@ -7218,8 +7218,6 @@ src/mame/video/usgames.c svneol=native#text/plain src/mame/video/vaportra.c svneol=native#text/plain src/mame/video/vastar.c svneol=native#text/plain src/mame/video/vball.c svneol=native#text/plain -src/mame/video/vdc.c svneol=native#text/plain -src/mame/video/vdc.h svneol=native#text/plain src/mame/video/vectrex.c svneol=native#text/plain src/mame/video/vendetta.c svneol=native#text/plain src/mame/video/vertigo.c svneol=native#text/plain diff --git a/src/mame/drivers/ggconnie.c b/src/mame/drivers/ggconnie.c index 887286d3ceb..7e207691e44 100644 --- a/src/mame/drivers/ggconnie.c +++ b/src/mame/drivers/ggconnie.c @@ -31,13 +31,11 @@ class ggconnie_state : public pce_common_state { public: ggconnie_state(const machine_config &mconfig, device_type type, const char *tag) - : pce_common_state(mconfig, type, tag), - m_huc6260(*this, "huc6260"), + : pce_common_state(mconfig, type, tag), m_rtc(*this, "rtc"), m_oki(*this, "oki") { } - required_device m_huc6260; required_device m_rtc; required_device m_oki; DECLARE_WRITE8_MEMBER(lamp_w); @@ -45,17 +43,8 @@ public: DECLARE_READ8_MEMBER(rtc_r); DECLARE_WRITE8_MEMBER(rtc_w); DECLARE_WRITE8_MEMBER(oki_bank_w); - DECLARE_WRITE_LINE_MEMBER(pce_irq_changed); - - UINT32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); }; -UINT32 ggconnie_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) -{ - m_huc6260->video_update( bitmap, cliprect ); - return 0; -} - WRITE8_MEMBER(ggconnie_state::lamp_w) { output_set_value("lamp", !BIT(data,0)); @@ -191,41 +180,17 @@ static const c6280_interface c6280_config = "maincpu" }; -WRITE_LINE_MEMBER(ggconnie_state::pce_irq_changed) -{ - m_maincpu->set_input_line(0, state); -} - - -#if 0 -static const huc6270_interface pce_huc6270_config = -{ - 0x10000, - DEVCB_DRIVER_LINE_MEMBER(ggconnie_state,pce_irq_changed) -}; - - -static const huc6260_interface pce_huc6260_config = -{ - DEVCB_DEVICE_MEMBER16( "huc6270", huc6270_device, next_pixel ), - DEVCB_DEVICE_MEMBER16( "huc6270", huc6270_device, time_until_next_event ), - DEVCB_DEVICE_LINE_MEMBER( "huc6270", huc6270_device, vsync_changed ), - DEVCB_DEVICE_LINE_MEMBER( "huc6270", huc6270_device, hsync_changed ) -}; -#endif - - static const huc6270_interface sgx_huc6270_0_config = { 0x10000, - DEVCB_DRIVER_LINE_MEMBER(ggconnie_state,pce_irq_changed) + DEVCB_DRIVER_LINE_MEMBER(pce_common_state,pce_irq_changed) }; static const huc6270_interface sgx_huc6270_1_config = { 0x10000, - DEVCB_DRIVER_LINE_MEMBER(ggconnie_state,pce_irq_changed) + DEVCB_DRIVER_LINE_MEMBER(pce_common_state,pce_irq_changed) }; diff --git a/src/mame/drivers/paranoia.c b/src/mame/drivers/paranoia.c index cb0477f2706..3d268ac8d89 100644 --- a/src/mame/drivers/paranoia.c +++ b/src/mame/drivers/paranoia.c @@ -38,12 +38,10 @@ HuC6280A (Hudson) #include "cpu/i8085/i8085.h" #include "machine/i8155.h" #include "machine/pcecommn.h" -#include "video/vdc.h" +#include "video/huc6260.h" +#include "video/huc6270.h" #include "cpu/h6280/h6280.h" #include "sound/c6280.h" -#include "drivlgcy.h" -#include "scrlegcy.h" - class paranoia_state : public pce_common_state { @@ -78,8 +76,8 @@ INPUT_PORTS_END static ADDRESS_MAP_START( pce_mem , AS_PROGRAM, 8, paranoia_state ) AM_RANGE( 0x000000, 0x03FFFF) AM_ROM AM_RANGE( 0x1F0000, 0x1F1FFF) AM_RAM AM_MIRROR(0x6000) - AM_RANGE( 0x1FE000, 0x1FE3FF) AM_READWRITE_LEGACY(vdc_0_r, vdc_0_w ) - AM_RANGE( 0x1FE400, 0x1FE7FF) AM_READWRITE_LEGACY(vce_r, vce_w ) + AM_RANGE( 0x1FE000, 0x1FE3FF) AM_DEVREADWRITE( "huc6270", huc6270_device, read, write ) + AM_RANGE( 0x1FE400, 0x1FE7FF) AM_DEVREADWRITE( "huc6260", huc6260_device, read, write ) AM_RANGE( 0x1FE800, 0x1FEBFF) AM_DEVREADWRITE("c6280", c6280_device, c6280_r, c6280_w ) AM_RANGE( 0x1FEC00, 0x1FEFFF) AM_DEVREADWRITE("maincpu", h6280_device, timer_r, timer_w ) AM_RANGE( 0x1FF000, 0x1FF3FF) AM_READWRITE(pce_joystick_r, pce_joystick_w ) @@ -87,7 +85,7 @@ static ADDRESS_MAP_START( pce_mem , AS_PROGRAM, 8, paranoia_state ) ADDRESS_MAP_END static ADDRESS_MAP_START( pce_io , AS_IO, 8, paranoia_state ) - AM_RANGE( 0x00, 0x03) AM_READWRITE_LEGACY(vdc_0_r, vdc_0_w ) + AM_RANGE( 0x00, 0x03) AM_DEVREADWRITE( "huc6270", huc6270_device, read, write ) ADDRESS_MAP_END WRITE8_MEMBER(paranoia_state::paranoia_8085_d000_w) @@ -176,13 +174,27 @@ static const c6280_interface c6280_config = "maincpu" }; + +static const huc6270_interface pce_huc6270_config = +{ + 0x10000, + DEVCB_DRIVER_LINE_MEMBER(pce_common_state,pce_irq_changed) +}; + + +static const huc6260_interface pce_huc6260_config = +{ + DEVCB_DEVICE_MEMBER16( "huc6270", huc6270_device, next_pixel ), + DEVCB_DEVICE_MEMBER16( "huc6270", huc6270_device, time_until_next_event ), + DEVCB_DEVICE_LINE_MEMBER( "huc6270", huc6270_device, vsync_changed ), + DEVCB_DEVICE_LINE_MEMBER( "huc6270", huc6270_device, hsync_changed ) +}; + static MACHINE_CONFIG_START( paranoia, paranoia_state ) /* basic machine hardware */ MCFG_CPU_ADD("maincpu", H6280, PCE_MAIN_CLOCK/3) MCFG_CPU_PROGRAM_MAP(pce_mem) MCFG_CPU_IO_MAP(pce_io) - MCFG_TIMER_ADD_SCANLINE("scantimer", pce_interrupt, "screen", 0, 1) - MCFG_QUANTUM_TIME(attotime::from_hz(60)) MCFG_CPU_ADD("sub", I8085A, 18000000/3) @@ -196,17 +208,13 @@ static MACHINE_CONFIG_START( paranoia, paranoia_state ) MCFG_I8155_ADD("i8155", 1000000 /*?*/, i8155_intf) /* video hardware */ - MCFG_SCREEN_ADD("screen", RASTER) - MCFG_SCREEN_RAW_PARAMS(PCE_MAIN_CLOCK/2, VDC_WPF, 70, 70 + 512 + 32, VDC_LPF, 14, 14+242) - MCFG_SCREEN_UPDATE_STATIC( pce ) - MCFG_SCREEN_PALETTE("palette") + MCFG_SCREEN_RAW_PARAMS(PCE_MAIN_CLOCK, HUC6260_WPF, 64, 64 + 1024 + 64, HUC6260_LPF, 18, 18 + 242) + MCFG_SCREEN_UPDATE_DRIVER( pce_common_state, screen_update ) + MCFG_SCREEN_PALETTE("huc6260:palette") - /* MCFG_GFXDECODE_ADD("gfxdecode", "palette", pce_gfxdecodeinfo ) */ - MCFG_PALETTE_ADD("palette", 1024) - MCFG_PALETTE_INIT_LEGACY( vce ) - - MCFG_VIDEO_START( pce ) + MCFG_HUC6260_ADD( "huc6260", PCE_MAIN_CLOCK, pce_huc6260_config ) + MCFG_HUC6270_ADD( "huc6270", pce_huc6270_config ) MCFG_SPEAKER_STANDARD_STEREO("lspeaker","rspeaker") MCFG_SOUND_ADD("c6280", C6280, PCE_MAIN_CLOCK/6) diff --git a/src/mame/drivers/tourvis.c b/src/mame/drivers/tourvis.c index 7f39363746c..1d42c409e9d 100644 --- a/src/mame/drivers/tourvis.c +++ b/src/mame/drivers/tourvis.c @@ -193,13 +193,11 @@ I can't tell ATM if units are seconds (even if values in tables seem very relate #include "emu.h" #include "cpu/i8085/i8085.h" #include "machine/pcecommn.h" -#include "video/vdc.h" +#include "video/huc6260.h" +#include "video/huc6270.h" #include "cpu/h6280/h6280.h" #include "sound/c6280.h" #include "machine/i8155.h" -#include "drivlgcy.h" -#include "scrlegcy.h" - class tourvision_state : public pce_common_state { @@ -213,6 +211,7 @@ public: DECLARE_WRITE8_MEMBER(tourvision_i8155_b_w); DECLARE_WRITE8_MEMBER(tourvision_i8155_c_w); DECLARE_WRITE_LINE_MEMBER(tourvision_timer_out); + DECLARE_WRITE_LINE_MEMBER(pce_irq_changed); required_device m_subcpu; }; @@ -296,8 +295,8 @@ INPUT_PORTS_END static ADDRESS_MAP_START( pce_mem , AS_PROGRAM, 8, tourvision_state ) AM_RANGE( 0x000000, 0x0FFFFF) AM_ROM AM_RANGE( 0x1F0000, 0x1F1FFF) AM_RAM AM_MIRROR(0x6000) - AM_RANGE( 0x1FE000, 0x1FE3FF) AM_READWRITE_LEGACY(vdc_0_r, vdc_0_w ) - AM_RANGE( 0x1FE400, 0x1FE7FF) AM_READWRITE_LEGACY(vce_r, vce_w ) + AM_RANGE( 0x1FE000, 0x1FE3FF) AM_DEVREADWRITE( "huc6270", huc6270_device, read, write ) + AM_RANGE( 0x1FE400, 0x1FE7FF) AM_DEVREADWRITE( "huc6260", huc6260_device, read, write ) AM_RANGE( 0x1FE800, 0x1FEBFF) AM_DEVREADWRITE("c6280", c6280_device, c6280_r, c6280_w ) AM_RANGE( 0x1FEC00, 0x1FEFFF) AM_DEVREADWRITE("maincpu", h6280_device, timer_r, timer_w ) AM_RANGE( 0x1FF000, 0x1FF3FF) AM_READWRITE(pce_joystick_r, pce_joystick_w ) @@ -305,7 +304,7 @@ static ADDRESS_MAP_START( pce_mem , AS_PROGRAM, 8, tourvision_state ) ADDRESS_MAP_END static ADDRESS_MAP_START( pce_io , AS_IO, 8, tourvision_state ) - AM_RANGE( 0x00, 0x03) AM_READWRITE_LEGACY(vdc_0_r, vdc_0_w ) + AM_RANGE( 0x00, 0x03) AM_DEVREADWRITE( "huc6270", huc6270_device, read, write ) ADDRESS_MAP_END WRITE8_MEMBER(tourvision_state::tourvision_8085_d000_w) @@ -364,30 +363,46 @@ static const c6280_interface c6280_config = "maincpu" }; +WRITE_LINE_MEMBER(tourvision_state::pce_irq_changed) +{ + m_maincpu->set_input_line(0, state); +} + + +static const huc6270_interface pce_huc6270_config = +{ + 0x10000, + DEVCB_DRIVER_LINE_MEMBER(tourvision_state,pce_irq_changed) +}; + + +static const huc6260_interface pce_huc6260_config = +{ + DEVCB_DEVICE_MEMBER16( "huc6270", huc6270_device, next_pixel ), + DEVCB_DEVICE_MEMBER16( "huc6270", huc6270_device, time_until_next_event ), + DEVCB_DEVICE_LINE_MEMBER( "huc6270", huc6270_device, vsync_changed ), + DEVCB_DEVICE_LINE_MEMBER( "huc6270", huc6270_device, hsync_changed ) +}; + static MACHINE_CONFIG_START( tourvision, tourvision_state ) /* basic machine hardware */ MCFG_CPU_ADD("maincpu", H6280, PCE_MAIN_CLOCK/3) MCFG_CPU_PROGRAM_MAP(pce_mem) MCFG_CPU_IO_MAP(pce_io) - MCFG_TIMER_ADD_SCANLINE("scantimer", pce_interrupt, "screen", 0, 1) - MCFG_QUANTUM_TIME(attotime::from_hz(60)) MCFG_CPU_ADD("subcpu", I8085A, 18000000/3 /*?*/) MCFG_CPU_PROGRAM_MAP(tourvision_8085_map) /* video hardware */ - MCFG_SCREEN_ADD("screen", RASTER) - MCFG_SCREEN_RAW_PARAMS(PCE_MAIN_CLOCK/2, VDC_WPF, 70, 70 + 512 + 32, VDC_LPF, 14, 14+242) - MCFG_SCREEN_UPDATE_STATIC( pce ) - MCFG_SCREEN_PALETTE("palette") + MCFG_SCREEN_RAW_PARAMS(PCE_MAIN_CLOCK, HUC6260_WPF, 64, 64 + 1024 + 64, HUC6260_LPF, 18, 18 + 242) + MCFG_SCREEN_UPDATE_DRIVER( pce_common_state, screen_update ) + MCFG_SCREEN_PALETTE("huc6260:palette") - /* MCFG_GFXDECODE_ADD("gfxdecode", "palette", pce_gfxdecodeinfo ) */ - MCFG_PALETTE_ADD("palette", 1024) - MCFG_PALETTE_INIT_LEGACY( vce ) + MCFG_HUC6260_ADD( "huc6260", PCE_MAIN_CLOCK, pce_huc6260_config ) + MCFG_HUC6270_ADD( "huc6270", pce_huc6270_config ) - MCFG_VIDEO_START( pce ) MCFG_I8155_ADD("i8155", 1000000 /*?*/, i8155_intf) diff --git a/src/mame/drivers/uapce.c b/src/mame/drivers/uapce.c index f2e601353f6..554b2412c88 100644 --- a/src/mame/drivers/uapce.c +++ b/src/mame/drivers/uapce.c @@ -93,12 +93,11 @@ Alien Crush & Pac_Land: dumps made from PC-Engine dumps of JP versions #include "emu.h" #include "cpu/z80/z80.h" #include "cpu/h6280/h6280.h" +#include "video/huc6260.h" +#include "video/huc6270.h" #include "sound/c6280.h" #include "machine/pcecommn.h" -#include "video/vdc.h" #include "sound/discrete.h" -#include "drivlgcy.h" -#include "scrlegcy.h" class uapce_state : public pce_common_state @@ -115,6 +114,7 @@ public: virtual UINT8 joy_read(); virtual void machine_reset(); required_device m_discrete; + DECLARE_WRITE_LINE_MEMBER(pce_irq_changed); }; #define UAPCE_SOUND_EN NODE_10 @@ -288,8 +288,8 @@ INPUT_PORTS_END static ADDRESS_MAP_START( pce_mem , AS_PROGRAM, 8, uapce_state ) AM_RANGE( 0x000000, 0x09FFFF) AM_ROM AM_RANGE( 0x1F0000, 0x1F1FFF) AM_RAM AM_MIRROR(0x6000) - AM_RANGE( 0x1FE000, 0x1FE3FF) AM_READWRITE_LEGACY(vdc_0_r, vdc_0_w ) - AM_RANGE( 0x1FE400, 0x1FE7FF) AM_READWRITE_LEGACY(vce_r, vce_w ) + AM_RANGE( 0x1FE000, 0x1FE3FF) AM_DEVREADWRITE( "huc6270", huc6270_device, read, write ) + AM_RANGE( 0x1FE400, 0x1FE7FF) AM_DEVREADWRITE( "huc6260", huc6260_device, read, write ) AM_RANGE( 0x1FE800, 0x1FEBFF) AM_DEVREADWRITE("c6280", c6280_device, c6280_r, c6280_w ) AM_RANGE( 0x1FEC00, 0x1FEFFF) AM_DEVREADWRITE("maincpu", h6280_device, timer_r, timer_w ) AM_RANGE( 0x1FF000, 0x1FF3FF) AM_READWRITE(pce_joystick_r, pce_joystick_w ) @@ -297,7 +297,7 @@ static ADDRESS_MAP_START( pce_mem , AS_PROGRAM, 8, uapce_state ) ADDRESS_MAP_END static ADDRESS_MAP_START( pce_io , AS_IO, 8, uapce_state ) - AM_RANGE( 0x00, 0x03) AM_READWRITE_LEGACY(vdc_0_r, vdc_0_w ) + AM_RANGE( 0x00, 0x03) AM_DEVREADWRITE( "huc6270", huc6270_device, read, write ) ADDRESS_MAP_END static const c6280_interface c6280_config = @@ -305,31 +305,45 @@ static const c6280_interface c6280_config = "maincpu" }; +WRITE_LINE_MEMBER(uapce_state::pce_irq_changed) +{ + m_maincpu->set_input_line(0, state); +} + + +static const huc6270_interface pce_huc6270_config = +{ + 0x10000, + DEVCB_DRIVER_LINE_MEMBER(uapce_state,pce_irq_changed) +}; + + +static const huc6260_interface pce_huc6260_config = +{ + DEVCB_DEVICE_MEMBER16( "huc6270", huc6270_device, next_pixel ), + DEVCB_DEVICE_MEMBER16( "huc6270", huc6270_device, time_until_next_event ), + DEVCB_DEVICE_LINE_MEMBER( "huc6270", huc6270_device, vsync_changed ), + DEVCB_DEVICE_LINE_MEMBER( "huc6270", huc6270_device, hsync_changed ) +}; static MACHINE_CONFIG_START( uapce, uapce_state ) /* basic machine hardware */ MCFG_CPU_ADD("maincpu", H6280, PCE_MAIN_CLOCK/3) MCFG_CPU_PROGRAM_MAP(pce_mem) MCFG_CPU_IO_MAP(pce_io) - MCFG_TIMER_ADD_SCANLINE("scantimer", pce_interrupt, "screen", 0, 1) MCFG_CPU_ADD("sub", Z80, 1400000) MCFG_CPU_PROGRAM_MAP(z80_map) MCFG_QUANTUM_TIME(attotime::from_hz(60)) - - + /* video hardware */ - MCFG_SCREEN_ADD("screen", RASTER) - MCFG_SCREEN_RAW_PARAMS(PCE_MAIN_CLOCK/2, VDC_WPF, 70, 70 + 512 + 32, VDC_LPF, 14, 14+242) - MCFG_SCREEN_UPDATE_STATIC( pce ) - MCFG_SCREEN_PALETTE("palette") + MCFG_SCREEN_RAW_PARAMS(PCE_MAIN_CLOCK, HUC6260_WPF, 64, 64 + 1024 + 64, HUC6260_LPF, 18, 18 + 242) + MCFG_SCREEN_UPDATE_DRIVER( pce_common_state, screen_update ) + MCFG_SCREEN_PALETTE("huc6260:palette") - /* MCFG_GFXDECODE_ADD("gfxdecode", "palette", pce_gfxdecodeinfo ) */ - MCFG_PALETTE_ADD("palette", 1024) - MCFG_PALETTE_INIT_LEGACY( vce ) - - MCFG_VIDEO_START( pce ) + MCFG_HUC6260_ADD( "huc6260", PCE_MAIN_CLOCK, pce_huc6260_config ) + MCFG_HUC6270_ADD( "huc6270", pce_huc6270_config ) MCFG_SPEAKER_STANDARD_STEREO("lspeaker","rspeaker") MCFG_SOUND_ADD("c6280", C6280, PCE_MAIN_CLOCK/6) diff --git a/src/mame/machine/pcecommn.c b/src/mame/machine/pcecommn.c index f502b2df679..ef6e85fa293 100644 --- a/src/mame/machine/pcecommn.c +++ b/src/mame/machine/pcecommn.c @@ -57,3 +57,15 @@ DRIVER_INIT_MEMBER(pce_common_state,pce_common) { m_io_port_options = PCE_JOY_SIG | CONST_SIG; } + +UINT32 pce_common_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +{ + m_huc6260->video_update( bitmap, cliprect ); + return 0; +} + +WRITE_LINE_MEMBER(pce_common_state::pce_irq_changed) +{ + m_maincpu->set_input_line(0, state); +} + diff --git a/src/mame/machine/pcecommn.h b/src/mame/machine/pcecommn.h index 3f616ba7eea..fbf1b600ac7 100644 --- a/src/mame/machine/pcecommn.h +++ b/src/mame/machine/pcecommn.h @@ -9,6 +9,8 @@ #ifndef PCECOMMON_H #define PCECOMMON_H +#include "video/huc6260.h" +#include "video/huc6270.h" #define PCE_MAIN_CLOCK 21477270 class pce_common_state : public driver_device @@ -16,7 +18,8 @@ class pce_common_state : public driver_device public: pce_common_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag), - m_maincpu(*this, "maincpu") { } + m_maincpu(*this, "maincpu"), + m_huc6260(*this, "huc6260") { } DECLARE_WRITE8_MEMBER(pce_joystick_w); DECLARE_READ8_MEMBER(pce_joystick_r); @@ -26,6 +29,9 @@ public: required_device m_maincpu; virtual UINT8 joy_read(); + UINT32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + required_device m_huc6260; + DECLARE_WRITE_LINE_MEMBER(pce_irq_changed); private: UINT8 m_io_port_options; /*driver-specific options for the PCE*/ int m_joystick_port_select; /* internal index of joystick ports */ diff --git a/src/mame/mame.mak b/src/mame/mame.mak index 02a23dd2d50..38d8af471ec 100644 --- a/src/mame/mame.mak +++ b/src/mame/mame.mak @@ -1490,7 +1490,7 @@ $(MAMEOBJ)/pce.a: \ $(DRIVERS)/paranoia.o \ $(DRIVERS)/tourvis.o \ $(DRIVERS)/uapce.o \ - $(MACHINE)/pcecommn.o $(VIDEO)/vdc.o \ + $(MACHINE)/pcecommn.o \ $(MAMEOBJ)/phoenix.a: \ $(DRIVERS)/naughtyb.o $(VIDEO)/naughtyb.o \ diff --git a/src/mame/video/vdc.c b/src/mame/video/vdc.c deleted file mode 100644 index 1e777de93f3..00000000000 --- a/src/mame/video/vdc.c +++ /dev/null @@ -1,1199 +0,0 @@ -#include "emu.h" -#include "video/vdc.h" - -/* VDC segments */ -#define STATE_VSW 0 -#define STATE_VDS 1 -#define STATE_VDW 2 -#define STATE_VCR 3 - -/* the VDC context */ - -struct VDC -{ - int dvssr_write; /* Set when the DVSSR register has been written to */ - int physical_width; /* Width of the display */ - int physical_height; /* Height of the display */ - UINT16 sprite_ram[64*4]; /* Sprite RAM */ - int curline; /* the current scanline we're on */ - int current_segment; /* current segment of display */ - int current_segment_line; /* current line inside a segment of display */ - int vblank_triggered; /* to indicate whether vblank has been triggered */ - int raster_count; /* counter to compare RCR against */ - int satb_countdown; /* scanlines to wait to trigger the SATB irq */ - UINT8 *vram; - UINT8 inc; - UINT8 vdc_register; - UINT8 vdc_latch; - PAIR16 vdc_data[32]; - int status; - int y_scroll; -}; - -struct VCE { - UINT8 vce_control; /* VCE control register */ - PAIR16 vce_address; /* Current address in the palette */ - PAIR16 vce_data[512]; /* Palette data */ - int current_bitmap_line; /* The current line in the display we are on */ - bitmap_ind16 *bmp; -}; - -struct VPC_PRIO { - UINT8 prio; - UINT8 vdc0_enabled; - UINT8 vdc1_enabled; -}; - -struct VPC { - VPC_PRIO vpc_prio[4]; - UINT8 prio_map[512]; /* Pre-calculated priority map */ - PAIR16 priority; /* Priority settings registers */ - PAIR16 window1; /* Window 1 setting */ - PAIR16 window2; /* Window 2 setting */ - UINT8 vdc_select; /* Which VDC do the ST0, ST1, and ST2 instructions write to */ -}; - -static VDC vdc[2]; -static VCE vce; -static VPC vpc; - -/* Function prototypes */ - -static void vdc_advance_line(running_machine &machine, int which); -static void draw_black_line(running_machine &machine, int line); -static void draw_overscan_line(int line); -static void draw_sgx_overscan_line(int line); -static void pce_refresh_line(int which, int line, int external_input, UINT8 *drawn, UINT16 *line_buffer); -static void pce_refresh_sprites(running_machine &machine, int which, int line, UINT8 *drawn, UINT16 *line_buffer); -static void vdc_do_dma(running_machine &machine, int which); -static void vpc_init( running_machine &machine ); - -TIMER_DEVICE_CALLBACK( pce_interrupt ) -{ - /* Draw the last scanline */ - if ( vce.current_bitmap_line >= 14 && vce.current_bitmap_line < 14 + 242 ) - { - /* We are in the active display area */ - /* First fill the line with the overscan color */ - draw_overscan_line(vce.current_bitmap_line ); - - /* Check if we need to draw more just the overscan color */ - if ( vdc[0].current_segment == STATE_VDW ) - { - /* 0 - no sprite and background pixels drawn - 1 - background pixel drawn - otherwise is 2 + sprite# */ - UINT8 drawn[VDC_WPF]; - /* our line buffer */ - UINT16 *line_buffer = &vce.bmp->pix16(vce.current_bitmap_line, 86 ); - - /* clear our priority/sprite collision detection buffer. */ - memset(drawn, 0, VDC_WPF); - - vdc[0].y_scroll = ( vdc[0].current_segment_line == 0 ) ? vdc[0].vdc_data[BYR].w : ( vdc[0].y_scroll + 1 ); - - /* Draw VDC #0 background layer */ - pce_refresh_line( 0, vdc[0].current_segment_line, 0, drawn, line_buffer); - - /* Draw VDC #0 sprite layer */ - if(vdc[0].vdc_data[CR].w & CR_SB) - { - pce_refresh_sprites(timer.machine(), 0, vdc[0].current_segment_line, drawn, line_buffer); - } - } - } - else - { - /* We are in one of the blanking areas */ - draw_black_line(timer.machine(), vce.current_bitmap_line ); - } - - /* bump current scanline */ - vce.current_bitmap_line = ( vce.current_bitmap_line + 1 ) % VDC_LPF; - vdc_advance_line(timer.machine(), 0 ); -} - -TIMER_DEVICE_CALLBACK( sgx_interrupt ) -{ - /* Draw the last scanline */ - if ( vce.current_bitmap_line >= 14 && vce.current_bitmap_line < 14 + 242 ) - { - /* We are in the active display area */ - /* First fill the line with the overscan color */ - draw_sgx_overscan_line(vce.current_bitmap_line ); - - /* Check if we need to draw more just the overscan color */ - if ( vdc[0].current_segment == STATE_VDW ) - { - /* 0 - no sprite and background pixels drawn - 1 - background pixel drawn - otherwise is 2 + sprite# */ - UINT8 drawn[2][512]; - UINT16 *line_buffer; - UINT16 temp_buffer[2][512]; - int i; - - /* clear our priority/sprite collision detection buffer. */ - memset( drawn, 0, sizeof(drawn) ); - - vdc[0].y_scroll = ( vdc[0].current_segment_line == 0 ) ? vdc[0].vdc_data[BYR].w : ( vdc[0].y_scroll + 1 ); - vdc[1].y_scroll = ( vdc[1].current_segment_line == 0 ) ? vdc[1].vdc_data[BYR].w : ( vdc[1].y_scroll + 1 ); - - /* Draw VDC #0 background layer */ - pce_refresh_line( 0, vdc[0].current_segment_line, 0, drawn[0], temp_buffer[0]); - - /* Draw VDC #0 sprite layer */ - if(vdc[0].vdc_data[CR].w & CR_SB) - { - pce_refresh_sprites(timer.machine(), 0, vdc[0].current_segment_line, drawn[0], temp_buffer[0]); - } - - /* Draw VDC #1 background layer */ - pce_refresh_line( 1, vdc[1].current_segment_line, 1, drawn[1], temp_buffer[1]); - - /* Draw VDC #1 sprite layer */ - if ( vdc[1].vdc_data[CR].w & CR_SB ) - { - pce_refresh_sprites(timer.machine(), 1, vdc[1].current_segment_line, drawn[1], temp_buffer[1]); - } - - line_buffer = &vce.bmp->pix16(vce.current_bitmap_line, 86 ); - /* Combine the output of both VDCs */ - for( i = 0; i < 512; i++ ) - { - int cur_prio = vpc.prio_map[i]; - - if ( vpc.vpc_prio[cur_prio].vdc0_enabled ) - { - if ( vpc.vpc_prio[cur_prio].vdc1_enabled ) - { - switch( vpc.vpc_prio[cur_prio].prio ) - { - case 0: /* BG1 SP1 BG0 SP0 */ - if ( drawn[0][i] ) - { - line_buffer[i] = temp_buffer[0][i]; - } - else if ( drawn[1][i] ) - { - line_buffer[i] = temp_buffer[1][i]; - } - break; - case 1: /* BG1 BG0 SP1 SP0 */ - if ( drawn[0][i] ) - { - if ( drawn[0][i] > 1 ) - { - line_buffer[i] = temp_buffer[0][i]; - } - else - { - if ( drawn[1][i] > 1 ) - { - line_buffer[i] = temp_buffer[1][i]; - } - else - { - line_buffer[i] = temp_buffer[0][i]; - } - } - } - else if ( drawn[1][i] ) - { - line_buffer[i] = temp_buffer[1][i]; - } - break; - case 2: /* BG1 + SP1 => SP1 - BG0 + SP1 => BG0 - BG0 + BG1 => BG0 - BG0 + SP0 => SP0 - BG1 + SP0 => BG1 - SP0 + SP1 => SP0 */ - if ( drawn[0][i] ) - { - if ( drawn[0][i] > 1 ) - { - if ( drawn[1][i] == 1 ) - { - line_buffer[i] = temp_buffer[1][i]; - } - else - { - line_buffer[i] = temp_buffer[0][i]; - } - } - else - { - line_buffer[i] = temp_buffer[0][i]; - } - } - else if ( drawn[1][i] ) - { - line_buffer[i] = temp_buffer[1][i]; - } - break; - } - } - else - { - if ( drawn[0][i] ) - { - line_buffer[i] = temp_buffer[0][i]; - } - } - } - else - { - if ( vpc.vpc_prio[cur_prio].vdc1_enabled ) - { - if ( drawn[1][i] ) - { - line_buffer[i] = temp_buffer[1][i]; - } - } - } - } - } - } - else - { - /* We are in one of the blanking areas */ - draw_black_line(timer.machine(), vce.current_bitmap_line ); - } - - /* bump current scanline */ - vce.current_bitmap_line = ( vce.current_bitmap_line + 1 ) % VDC_LPF; - vdc_advance_line(timer.machine(), 0 ); - vdc_advance_line(timer.machine(), 1 ); -} - -static void vdc_advance_line(running_machine &machine, int which) -{ - int ret = 0; - - vdc[which].curline += 1; - vdc[which].current_segment_line += 1; - vdc[which].raster_count += 1; - - if ( vdc[which].satb_countdown ) - { - vdc[which].satb_countdown -= 1; - if ( vdc[which].satb_countdown == 0 ) - { - if ( vdc[which].vdc_data[DCR].w & DCR_DSC ) - { - vdc[which].status |= VDC_DS; /* set satb done flag */ - ret = 1; - } - } - } - - if ( vce.current_bitmap_line == 0 ) - { - vdc[which].current_segment = STATE_VSW; - vdc[which].current_segment_line = 0; - vdc[which].vblank_triggered = 0; - vdc[which].curline = 0; - } - - if ( STATE_VSW == vdc[which].current_segment && vdc[which].current_segment_line >= ( vdc[which].vdc_data[VPR].b.l & 0x1F ) ) - { - vdc[which].current_segment = STATE_VDS; - vdc[which].current_segment_line = 0; - } - - if ( STATE_VDS == vdc[which].current_segment && vdc[which].current_segment_line >= vdc[which].vdc_data[VPR].b.h ) - { - vdc[which].current_segment = STATE_VDW; - vdc[which].current_segment_line = 0; - vdc[which].raster_count = 0x40; - } - - if ( STATE_VDW == vdc[which].current_segment && vdc[which].current_segment_line > ( vdc[which].vdc_data[VDW].w & 0x01FF ) ) - { - vdc[which].current_segment = STATE_VCR; - vdc[which].current_segment_line = 0; - - /* Generate VBlank interrupt, sprite DMA */ - vdc[which].vblank_triggered = 1; - if ( vdc[which].vdc_data[CR].w & CR_VR ) - { - vdc[which].status |= VDC_VD; - ret = 1; - } - - /* do VRAM > SATB DMA if the enable bit is set or the DVSSR reg. was written to */ - if( ( vdc[which].vdc_data[DCR].w & DCR_DSR ) || vdc[which].dvssr_write ) - { - int i; - - vdc[which].dvssr_write = 0; - - for( i = 0; i < 256; i++ ) - { - vdc[which].sprite_ram[i] = ( vdc[which].vram[ ( vdc[which].vdc_data[DVSSR].w << 1 ) + i * 2 + 1 ] << 8 ) | vdc[which].vram[ ( vdc[which].vdc_data[DVSSR].w << 1 ) + i * 2 ]; - } - - /* generate interrupt if needed */ - if ( vdc[which].vdc_data[DCR].w & DCR_DSC ) - { - vdc[which].satb_countdown = 4; - } - } - } - - if ( STATE_VCR == vdc[which].current_segment ) - { - if ( vdc[which].current_segment_line >= 3 && vdc[which].current_segment_line >= vdc[which].vdc_data[VCR].b.l ) - { - vdc[which].current_segment = STATE_VSW; - vdc[which].current_segment_line = 0; - vdc[which].curline = 0; - } - } - - /* generate interrupt on line compare if necessary */ - if ( vdc[which].raster_count == vdc[which].vdc_data[RCR].w && vdc[which].vdc_data[CR].w & CR_RC ) - { - vdc[which].status |= VDC_RR; - ret = 1; - } - - /* handle frame events */ - if(vdc[which].curline == 261 && ! vdc[which].vblank_triggered ) - { - vdc[which].vblank_triggered = 1; - if(vdc[which].vdc_data[CR].w & CR_VR) - { /* generate IRQ1 if enabled */ - vdc[which].status |= VDC_VD; /* set vblank flag */ - ret = 1; - } - - /* do VRAM > SATB DMA if the enable bit is set or the DVSSR reg. was written to */ - if ( ( vdc[which].vdc_data[DCR].w & DCR_DSR ) || vdc[which].dvssr_write ) - { - int i; - - vdc[which].dvssr_write = 0; -#ifdef MAME_DEBUG - assert(((vdc[which].vdc_data[DVSSR].w<<1) + 512) <= 0x10000); -#endif - for( i = 0; i < 256; i++ ) - { - vdc[which].sprite_ram[i] = ( vdc[which].vram[ ( vdc[which].vdc_data[DVSSR].w << 1 ) + i * 2 + 1 ] << 8 ) | vdc[which].vram[ ( vdc[which].vdc_data[DVSSR].w << 1 ) + i * 2 ]; - } - - /* generate interrupt if needed */ - if(vdc[which].vdc_data[DCR].w & DCR_DSC) - { - vdc[which].satb_countdown = 4; - } - } - } - - if (ret) - machine.device("maincpu")->execute().set_input_line(0, HOLD_LINE); -} - -VIDEO_START( pce ) -{ - logerror("*** pce_vh_start\n"); - - /* clear context */ - memset(&vdc, 0, sizeof(vdc)); - memset(&vce, 0, sizeof(vce)); - memset(&vpc, 0, sizeof(vpc)); - - /* allocate VRAM */ - vdc[0].vram = auto_alloc_array(machine, UINT8, 0x10000); - vdc[1].vram = auto_alloc_array(machine, UINT8, 0x10000); - memset(vdc[0].vram, 0, 0x10000); - memset(vdc[1].vram, 0, 0x10000); - - /* create display bitmap */ - vce.bmp = auto_bitmap_ind16_alloc(machine, machine.first_screen()->width(), machine.first_screen()->height()); - - vdc[0].inc = 1; - vdc[1].inc = 1; - - vpc_init(machine); -} - - -SCREEN_UPDATE_IND16( pce ) -{ - /* copy our rendering buffer to the display */ - copybitmap (bitmap,*vce.bmp,0,0,0,0,cliprect); - return 0; -} - -static void draw_black_line(running_machine &machine, int line) -{ - palette_device *m_palette=machine.first_screen()->palette(); - int i; - - /* our line buffer */ - UINT16 *line_buffer = &vce.bmp->pix16(line); - - for( i=0; i< VDC_WPF; i++ ) - line_buffer[i] = m_palette->black_pen(); -} - -static void draw_overscan_line(int line) -{ - int i; - - /* Are we in greyscale mode or in color mode? */ - int color_base = vce.vce_control & 0x80 ? 512 : 0; - - /* our line buffer */ - UINT16 *line_buffer = &vce.bmp->pix16(line); - - for ( i = 0; i < VDC_WPF; i++ ) - line_buffer[i] = color_base + vce.vce_data[0x100].w; -} - -static void draw_sgx_overscan_line(int line) -{ - int i; - - /* Are we in greyscale mode or in color mode? */ - int color_base = vce.vce_control & 0x80 ? 512 : 0; - - /* our line buffer */ - UINT16 *line_buffer = &vce.bmp->pix16(line); - - for ( i = 0; i < VDC_WPF; i++ ) - line_buffer[i] = color_base + vce.vce_data[0].w; -} - -static void vram_write(int which, offs_t offset, UINT8 data) -{ - if(offset & 0x10000) - { - logerror("VDC #%d: Write to VRAM offset %05X\n", which, offset); - return; - } - else - { - vdc[which].vram[offset] = data; - } -} - -static UINT8 vram_read(int which, offs_t offset) -{ - UINT8 temp; - - if(offset & 0x10000) - { - temp = vdc[which].vram[offset & 0xFFFF]; - } - else - { - temp = vdc[which].vram[offset]; - } - - return temp; -} - - -static void vdc_w( running_machine &machine, int which, offs_t offset, UINT8 data ) -{ - switch(offset&3) - { - case 0x00: /* VDC register select */ - vdc[which].vdc_register = (data & 0x1F); - break; - - case 0x02: /* VDC data (LSB) */ - vdc[which].vdc_data[vdc[which].vdc_register].b.l = data; - switch(vdc[which].vdc_register) - { - case VxR: /* LSB of data to write to VRAM */ - vdc[which].vdc_latch = data; - break; - - case BYR: - vdc[which].y_scroll=vdc[which].vdc_data[BYR].w; - break; - - case HDR: - vdc[which].physical_width = ((data & 0x003F) + 1) << 3; - break; - - case VDW: - vdc[which].physical_height &= 0xFF00; - vdc[which].physical_height |= (data & 0xFF); - vdc[which].physical_height &= 0x01FF; - break; - - case LENR: -// logerror("LENR LSB = %02X\n", data); - break; - case SOUR: -// logerror("SOUR LSB = %02X\n", data); - break; - case DESR: -// logerror("DESR LSB = %02X\n", data); - break; - } - break; - - case 0x03: /* VDC data (MSB) */ - vdc[which].vdc_data[vdc[which].vdc_register].b.h = data; - switch(vdc[which].vdc_register) - { - case VxR: /* MSB of data to write to VRAM */ - vram_write(which, vdc[which].vdc_data[MAWR].w*2+0, vdc[which].vdc_latch); - vram_write(which, vdc[which].vdc_data[MAWR].w*2+1, data); - vdc[which].vdc_data[MAWR].w += vdc[which].inc; - break; - - case CR: - { - static const unsigned char inctab[] = {1, 32, 64, 128}; - vdc[which].inc = inctab[(data >> 3) & 3]; - } - break; - - case VDW: - vdc[which].physical_height &= 0x00FF; - vdc[which].physical_height |= (data << 8); - vdc[which].physical_height &= 0x01FF; - break; - - case DVSSR: - /* Force VRAM <> SATB DMA for this frame */ - vdc[which].dvssr_write = 1; - break; - - case BYR: - vdc[which].y_scroll=vdc[which].vdc_data[BYR].w; - break; - - case LENR: - vdc_do_dma( machine, which ); - break; - case SOUR: -// logerror("SOUR MSB = %02X\n", data); - break; - case DESR: -// logerror("DESR MSB = %02X\n", data); - break; - } - break; - } -} - -static UINT8 vdc_r( running_machine &machine, int which, offs_t offset ) -{ - int temp = 0; - switch(offset & 3) - { - case 0x00: - temp = vdc[which].status; - vdc[which].status &= ~(VDC_VD | VDC_DV | VDC_DS | VDC_RR | VDC_OR | VDC_CR); - machine.device("maincpu")->execute().set_input_line(0, CLEAR_LINE); - break; - - case 0x02: - temp = vram_read(which, vdc[which].vdc_data[MARR].w * 2 + 0); - break; - - case 0x03: - temp = vram_read(which, vdc[which].vdc_data[MARR].w * 2 + 1); - if ( vdc[which].vdc_register == VxR ) - { - vdc[which].vdc_data[MARR].w += vdc[which].inc; - } - break; - } - return (temp); -} - -WRITE8_HANDLER( vdc_0_w ) { vdc_w( space.machine(), 0, offset, data ); } -WRITE8_HANDLER( vdc_1_w ) { vdc_w( space.machine(), 1, offset, data ); } -READ8_HANDLER( vdc_0_r ) { return vdc_r( space.machine(), 0, offset ); } -READ8_HANDLER( vdc_1_r ) { return vdc_r( space.machine(), 1, offset ); } - -PALETTE_INIT( vce ) -{ - int i; - - for( i = 0; i < 512; i++ ) - { - int r = (( i >> 3) & 7) << 5; - int g = (( i >> 6) & 7) << 5; - int b = (( i ) & 7) << 5; - int y = ( ( 66 * r + 129 * g + 25 * b + 128) >> 8) + 16; - palette.set_pen_color(i, r, g, b); - palette.set_pen_color(512+i, y, y, y); - } -} - - READ8_HANDLER ( vce_r ) -{ - int temp = 0xFF; - switch(offset & 7) - { - case 0x04: /* color table data (LSB) */ - temp = vce.vce_data[vce.vce_address.w].b.l; - break; - - case 0x05: /* color table data (MSB) */ - temp = vce.vce_data[vce.vce_address.w].b.h; - temp |= 0xFE; - vce.vce_address.w = (vce.vce_address.w + 1) & 0x01FF; - break; - } - return (temp); -} - - -WRITE8_HANDLER ( vce_w ) -{ - switch(offset & 7) - { - case 0x00: /* control reg. */ - vce.vce_control = data; - break; - - case 0x02: /* color table address (LSB) */ - vce.vce_address.b.l = data; - vce.vce_address.w &= 0x1FF; - break; - - case 0x03: /* color table address (MSB) */ - vce.vce_address.b.h = data; - vce.vce_address.w &= 0x1FF; - break; - - case 0x04: /* color table data (LSB) */ - vce.vce_data[vce.vce_address.w].b.l = data; - break; - - case 0x05: /* color table data (MSB) */ - vce.vce_data[vce.vce_address.w].b.h = data & 0x01; - - /* bump internal address */ - vce.vce_address.w = (vce.vce_address.w + 1) & 0x01FF; - break; - } -} - - -static void pce_refresh_line(int which, int line, int external_input, UINT8 *drawn, UINT16 *line_buffer) -{ - static const int width_table[4] = {5, 6, 7, 7}; - - int scroll_y = ( vdc[which].y_scroll & 0x01FF); - int scroll_x = (vdc[which].vdc_data[BXR].w & 0x03FF); - int nt_index; - - /* is virtual map 32 or 64 characters tall ? (256 or 512 pixels) */ - int v_line = (scroll_y) & (vdc[which].vdc_data[MWR].w & 0x0040 ? 0x1FF : 0x0FF); - - /* row within character */ - int v_row = (v_line & 7); - - /* row of characters in BAT */ - int nt_row = (v_line >> 3); - - /* virtual X size (# bits to shift) */ - int v_width = width_table[(vdc[which].vdc_data[MWR].w >> 4) & 3]; - - /* pointer to the name table (Background Attribute Table) in VRAM */ - UINT8 *bat = &(vdc[which].vram[nt_row << (v_width+1)]); - - /* Are we in greyscale mode or in color mode? */ - int color_base = vce.vce_control & 0x80 ? 512 : 0; - - int b0, b1, b2, b3; - int i0, i1, i2, i3; - int cell_pattern_index; - int cell_palette; - int x, c, i; - - /* character blanking bit */ - if(!(vdc[which].vdc_data[CR].w & CR_BB)) - { - return; - } - else - { - int pixel = 0; - int phys_x = - ( scroll_x & 0x07 ); - - for(i=0;i<(vdc[which].physical_width >> 3) + 1;i++) - { - nt_index = (i + (scroll_x >> 3)) & ((2 << (v_width-1))-1); - nt_index *= 2; - - /* get name table data: */ - - /* palette # = index from 0-15 */ - cell_palette = ( bat[nt_index + 1] >> 4 ) & 0x0F; - - /* This is the 'character number', from 0-0x0FFF */ - /* then it is shifted left 4 bits to form a VRAM address */ - /* and one more bit to convert VRAM word offset to a */ - /* byte-offset within the VRAM space */ - cell_pattern_index = ( ( ( bat[nt_index + 1] << 8 ) | bat[nt_index] ) & 0x0FFF) << 5; - - b0 = vram_read(which, (cell_pattern_index) + (v_row << 1) + 0x00); - b1 = vram_read(which, (cell_pattern_index) + (v_row << 1) + 0x01); - b2 = vram_read(which, (cell_pattern_index) + (v_row << 1) + 0x10); - b3 = vram_read(which, (cell_pattern_index) + (v_row << 1) + 0x11); - - for(x=0;x<8;x++) - { - i0 = (b0 >> (7-x)) & 1; - i1 = (b1 >> (7-x)) & 1; - i2 = (b2 >> (7-x)) & 1; - i3 = (b3 >> (7-x)) & 1; - c = (cell_palette << 4 | i3 << 3 | i2 << 2 | i1 << 1 | i0); - - /* colour #0 always comes from palette #0 */ - if ( ! ( c & 0x0F ) ) - c &= 0x0F; - - if ( phys_x >= 0 && phys_x < vdc[which].physical_width ) - { - drawn[ pixel ] = c ? 1 : 0; - if ( c || ! external_input ) - line_buffer[ pixel ] = color_base + vce.vce_data[c].w; - pixel++; - if ( vdc[which].physical_width != 512 ) - { - while ( pixel < ( ( ( phys_x + 1 ) * 512 ) / vdc[which].physical_width ) ) - { - drawn[ pixel ] = c ? 1 : 0; - if ( c || ! external_input ) - line_buffer[ pixel ] = color_base + vce.vce_data[c].w; - pixel++; - } - } - } - phys_x += 1; - } - } - } -} - - - -static void conv_obj(int which, int i, int l, int hf, int vf, char *buf) -{ - int b0, b1, b2, b3, i0, i1, i2, i3, x; - int xi; - int tmp; - - l &= 0x0F; - if(vf) l = (15 - l); - - tmp = l + ( i << 5); - - b0 = vram_read(which, (tmp + 0x00)<<1); - b0 |= vram_read(which, ((tmp + 0x00)<<1)+1)<<8; - b1 = vram_read(which, (tmp + 0x10)<<1); - b1 |= vram_read(which, ((tmp + 0x10)<<1)+1)<<8; - b2 = vram_read(which, (tmp + 0x20)<<1); - b2 |= vram_read(which, ((tmp + 0x20)<<1)+1)<<8; - b3 = vram_read(which, (tmp + 0x30)<<1); - b3 |= vram_read(which, ((tmp + 0x30)<<1)+1)<<8; - - for(x=0;x<16;x++) - { - if(hf) xi = x; else xi = (15 - x); - i0 = (b0 >> xi) & 1; - i1 = (b1 >> xi) & 1; - i2 = (b2 >> xi) & 1; - i3 = (b3 >> xi) & 1; - buf[x] = (i3 << 3 | i2 << 2 | i1 << 1 | i0); - } -} - -static void pce_refresh_sprites(running_machine &machine, int which, int line, UINT8 *drawn, UINT16 *line_buffer) -{ - int i; - UINT8 sprites_drawn = 0; - - /* Are we in greyscale mode or in color mode? */ - int color_base = vce.vce_control & 0x80 ? 512 : 0; - - /* count up: Highest priority is Sprite 0 */ - for(i = 0; i < 64; i++) - { - static const int cgy_table[] = {16, 32, 64, 64}; - - int obj_y = (vdc[which].sprite_ram[(i << 2) + 0] & 0x03FF) - 64; - int obj_x = (vdc[which].sprite_ram[(i << 2) + 1] & 0x03FF) - 32; - int obj_i = (vdc[which].sprite_ram[(i << 2) + 2] & 0x07FE); - int obj_a = (vdc[which].sprite_ram[(i << 2) + 3]); - int cgx = (obj_a >> 8) & 1; /* sprite width */ - int cgy = (obj_a >> 12) & 3; /* sprite height */ - int hf = (obj_a >> 11) & 1; /* horizontal flip */ - int vf = (obj_a >> 15) & 1; /* vertical flip */ - int palette = (obj_a & 0x000F); - int priority = (obj_a >> 7) & 1; - int obj_h = cgy_table[cgy]; - int obj_l = (line - obj_y); - int cgypos; - char buf[16]; - - if ((obj_y == -64) || (obj_y > line)) continue; - if ((obj_x == -32) || (obj_x >= vdc[which].physical_width)) continue; - - /* no need to draw an object that's ABOVE where we are. */ - if((obj_y + obj_h) < line) continue; - - /* If CGX is set, bit 0 of sprite pattern index is forced to 0 */ - if ( cgx ) - obj_i &= ~2; - - /* If CGY is set to 1, bit 1 of the sprite pattern index is forced to 0. */ - if ( cgy & 1 ) - obj_i &= ~4; - - /* If CGY is set to 2 or 3, bit 1 and 2 of the sprite pattern index are forced to 0. */ - if ( cgy & 2 ) - obj_i &= ~12; - - if (obj_l < obj_h) - { - sprites_drawn++; - if(sprites_drawn > 16) - { - if(vdc[which].vdc_data[CR].w & CR_OV) - { - /* note: flag is set only if irq is taken, Mizubaku Daibouken relies on this behaviour */ - vdc[which].status |= VDC_OR; - machine.device("maincpu")->execute().set_input_line(0, ASSERT_LINE); - } - continue; /* Should cause an interrupt */ - } - - cgypos = (obj_l >> 4); - if(vf) cgypos = ((obj_h - 1) >> 4) - cgypos; - - if(cgx == 0) - { - int x; - int pixel_x = ( ( obj_x * 512 ) / vdc[which].physical_width ); - - conv_obj(which, obj_i + (cgypos << 2), obj_l, hf, vf, buf); - - for(x = 0; x < 16; x++) - { - if(((obj_x + x) < (vdc[which].physical_width)) && ((obj_x + x) >= 0)) - { - if ( buf[x] ) - { - if( drawn[pixel_x] < 2 ) - { - if( priority || drawn[pixel_x] == 0 ) - { - line_buffer[pixel_x] = color_base + vce.vce_data[0x100 + (palette << 4) + buf[x]].w; - if ( vdc[which].physical_width != 512 ) - { - int dp = 1; - while ( pixel_x + dp < ( ( ( obj_x + x + 1 ) * 512 ) / vdc[which].physical_width ) ) - { - drawn[pixel_x + dp] = i + 2; - line_buffer[pixel_x + dp] = color_base + vce.vce_data[0x100 + (palette << 4) + buf[x]].w; - dp++; - } - } - } - drawn[pixel_x] = i + 2; - } - /* Check for sprite #0 collision */ - else if (drawn[pixel_x] == 2) - { - if(vdc[which].vdc_data[CR].w & CR_CC) - machine.device("maincpu")->execute().set_input_line(0, ASSERT_LINE); - vdc[which].status |= VDC_CR; - } - } - } - if ( vdc[which].physical_width != 512 ) - { - pixel_x = ( ( obj_x + x + 1 ) * 512 ) / vdc[which].physical_width; - } - else - { - pixel_x += 1; - } - } - } - else - { - int x; - int pixel_x = ( ( obj_x * 512 ) / vdc[which].physical_width ); - - conv_obj(which, obj_i + (cgypos << 2) + (hf ? 2 : 0), obj_l, hf, vf, buf); - - for(x = 0; x < 16; x++) - { - if(((obj_x + x) < (vdc[which].physical_width)) && ((obj_x + x) >= 0)) - { - if ( buf[x] ) - { - if( drawn[pixel_x] < 2 ) - { - if ( priority || drawn[pixel_x] == 0 ) - { - line_buffer[pixel_x] = color_base + vce.vce_data[0x100 + (palette << 4) + buf[x]].w; - if ( vdc[which].physical_width != 512 ) - { - int dp = 1; - while ( pixel_x + dp < ( ( ( obj_x + x + 1 ) * 512 ) / vdc[which].physical_width ) ) - { - drawn[pixel_x + dp] = i + 2; - line_buffer[pixel_x + dp] = color_base + vce.vce_data[0x100 + (palette << 4) + buf[x]].w; - dp++; - } - } - } - drawn[pixel_x] = i + 2; - } - /* Check for sprite #0 collision */ - else if ( drawn[pixel_x] == 2 ) - { - if(vdc[which].vdc_data[CR].w & CR_CC) - machine.device("maincpu")->execute().set_input_line(0, ASSERT_LINE); - vdc[which].status |= VDC_CR; - } - } - } - if ( vdc[which].physical_width != 512 ) - { - pixel_x = ( ( obj_x + x + 1 ) * 512 ) / vdc[which].physical_width; - } - else - { - pixel_x += 1; - } - } - - /* 32 pixel wide sprites are counted as 2 sprites and the right half - is only drawn if there are 2 open slots. - */ - sprites_drawn++; - if( sprites_drawn > 16 ) - { - if(vdc[which].vdc_data[CR].w&CR_OV) - { - /* note: flag is set only if irq is taken, Mizubaku Daibouken relies on this behaviour */ - vdc[which].status |= VDC_OR; - machine.device("maincpu")->execute().set_input_line(0, ASSERT_LINE); - } - } - else - { - conv_obj(which, obj_i + (cgypos << 2) + (hf ? 0 : 2), obj_l, hf, vf, buf); - for(x = 0; x < 16; x++) - { - if(((obj_x + 0x10 + x) < (vdc[which].physical_width)) && ((obj_x + 0x10 + x) >= 0)) - { - if ( buf[x] ) - { - if( drawn[pixel_x] < 2 ) - { - if( priority || drawn[pixel_x] == 0 ) - { - line_buffer[pixel_x] = color_base + vce.vce_data[0x100 + (palette << 4) + buf[x]].w; - if ( vdc[which].physical_width != 512 ) - { - int dp = 1; - while ( pixel_x + dp < ( ( ( obj_x + x + 17 ) * 512 ) / vdc[which].physical_width ) ) - { - drawn[pixel_x + dp] = i + 2; - line_buffer[pixel_x + dp] = color_base + vce.vce_data[0x100 + (palette << 4) + buf[x]].w; - dp++; - } - } - } - drawn[pixel_x] = i + 2; - } - /* Check for sprite #0 collision */ - else if ( drawn[pixel_x] == 2 ) - { - if(vdc[which].vdc_data[CR].w & CR_CC) - machine.device("maincpu")->execute().set_input_line(0, ASSERT_LINE); - vdc[which].status |= VDC_CR; - } - } - } - if ( vdc[which].physical_width != 512 ) - { - pixel_x = ( ( obj_x + x + 17 ) * 512 ) / vdc[which].physical_width; - } - else - { - pixel_x += 1; - } - } - } - } - } - } -} - -static void vdc_do_dma(running_machine &machine, int which) -{ - int src = vdc[which].vdc_data[SOUR].w; - int dst = vdc[which].vdc_data[DESR].w; - int len = vdc[which].vdc_data[LENR].w; - - int did = (vdc[which].vdc_data[DCR].w >> 3) & 1; - int sid = (vdc[which].vdc_data[DCR].w >> 2) & 1; - int dvc = (vdc[which].vdc_data[DCR].w >> 1) & 1; - - do { - UINT8 l, h; - - l = vram_read(which, src<<1); - h = vram_read(which, (src<<1) + 1); - - vram_write(which, dst<<1,l); - vram_write(which, 1+(dst<<1),h); - - if(sid) src = (src - 1) & 0xFFFF; - else src = (src + 1) & 0xFFFF; - - if(did) dst = (dst - 1) & 0xFFFF; - else dst = (dst + 1) & 0xFFFF; - - len = (len - 1) & 0xFFFF; - - } while (len != 0xFFFF); - - vdc[which].status |= VDC_DV; - vdc[which].vdc_data[SOUR].w = src; - vdc[which].vdc_data[DESR].w = dst; - vdc[which].vdc_data[LENR].w = len; - if(dvc) - { - machine.device("maincpu")->execute().set_input_line(0, ASSERT_LINE); - } - -} - -static void vpc_update_prio_map( void ) -{ - int i; - - for( i = 0; i < 512; i++ ) - { - vpc.prio_map[i] = 0; - if ( vpc.window1.w < 0x40 || i > vpc.window1.w ) - { - vpc.prio_map[i] |= 1; - } - if ( vpc.window2.w < 0x40 || i > vpc.window2.w ) - { - vpc.prio_map[i] |= 2; - } - } -} - -WRITE8_HANDLER( vpc_w ) -{ -//if ( offset < 2 ) -//printf("VPC write offset %02X, data %02X\n", offset, data ); - switch( offset & 0x07 ) - { - case 0x00: /* Priority register #0 */ - vpc.priority.b.l = data; - vpc.vpc_prio[0].prio = ( data >> 2 ) & 3; - vpc.vpc_prio[0].vdc0_enabled = data & 1; - vpc.vpc_prio[0].vdc1_enabled = data & 2; - vpc.vpc_prio[1].prio = ( data >> 6 ) & 3; - vpc.vpc_prio[1].vdc0_enabled = data & 0x10; - vpc.vpc_prio[1].vdc1_enabled = data & 0x20; - break; - case 0x01: /* Priority register #1 */ - vpc.priority.b.h = data; - vpc.vpc_prio[2].prio = ( data >> 2 ) & 3; - vpc.vpc_prio[2].vdc0_enabled = data & 1; - vpc.vpc_prio[2].vdc1_enabled = data & 2; - vpc.vpc_prio[3].prio = ( data >> 6 ) & 3; - vpc.vpc_prio[3].vdc0_enabled = data & 0x10; - vpc.vpc_prio[3].vdc1_enabled = data & 0x20; - break; - case 0x02: /* Window 1 LSB */ - vpc.window1.b.l = data; - vpc_update_prio_map(); - break; - case 0x03: /* Window 1 MSB */ - vpc.window1.b.h = data & 3; - vpc_update_prio_map(); - break; - case 0x04: /* Window 2 LSB */ - vpc.window2.b.l = data; - vpc_update_prio_map(); - break; - case 0x05: /* Window 2 MSB */ - vpc.window2.b.h = data & 3; - vpc_update_prio_map(); - break; - case 0x06: /* VDC I/O select */ - vpc.vdc_select = data & 1; - break; - } -} - -READ8_HANDLER( vpc_r ) -{ - UINT8 data = 0; - switch( offset & 0x07 ) - { - case 0x00: /* Priority register #0 */ - data = vpc.priority.b.l; - break; - case 0x01: /* Priority register #1 */ - data = vpc.priority.b.h; - break; - case 0x02: /* Window 1 LSB */ - data = vpc.window1.b.l; - break; - case 0x03: /* Window 1 MSB; high bits are 0 or 1? */ - data = vpc.window1.b.h; - break; - case 0x04: /* Window 2 LSB */ - data = vpc.window2.b.l; - break; - case 0x05: /* Window 2 MSB; high bits are 0 or 1? */ - data = vpc.window2.b.h; - break; - } - return data; -} - -static void vpc_init( running_machine &machine ) -{ - address_space &space = machine.device("maincpu")->memory().space(AS_PROGRAM); - vpc_w( space, 0, 0x11 ); - vpc_w( space, 1, 0x11 ); - vpc.window1.w = 0; - vpc.window2.w = 0; - vpc.vdc_select = 0; -} - -WRITE8_HANDLER( sgx_vdc_w ) -{ - if ( vpc.vdc_select ) - { - vdc_1_w( space, offset, data ); - } - else - { - vdc_0_w( space, offset, data ); - } -} - -READ8_HANDLER( sgx_vdc_r ) -{ - return ( vpc.vdc_select ) ? vdc_1_r( space, offset ) : vdc_0_r( space, offset ); -} diff --git a/src/mame/video/vdc.h b/src/mame/video/vdc.h deleted file mode 100644 index e2e2d23a0f9..00000000000 --- a/src/mame/video/vdc.h +++ /dev/null @@ -1,51 +0,0 @@ - -VIDEO_START( pce ); -SCREEN_UPDATE_IND16( pce ); -DECLARE_WRITE8_HANDLER ( vdc_0_w ); -DECLARE_WRITE8_HANDLER ( vdc_1_w ); - DECLARE_READ8_HANDLER ( vdc_0_r ); - DECLARE_READ8_HANDLER ( vdc_1_r ); -PALETTE_INIT( vce ); - DECLARE_READ8_HANDLER ( vce_r ); -DECLARE_WRITE8_HANDLER ( vce_w ); -DECLARE_WRITE8_HANDLER( vpc_w ); - DECLARE_READ8_HANDLER( vpc_r ); -DECLARE_WRITE8_HANDLER( sgx_vdc_w ); - DECLARE_READ8_HANDLER( sgx_vdc_r ); -TIMER_DEVICE_CALLBACK( pce_interrupt ); -TIMER_DEVICE_CALLBACK( sgx_interrupt ); - -/* Screen timing stuff */ - -#define VDC_WPF 684 /* width of a line in frame including blanking areas */ -#define VDC_LPF 262 /* number of lines in a single frame */ - -/* Bits in the VDC status register */ - -#define VDC_BSY 0x40 /* Set when the VDC accesses VRAM */ -#define VDC_VD 0x20 /* Set when in the vertical blanking period */ -#define VDC_DV 0x10 /* Set when a VRAM > VRAM DMA transfer is done */ -#define VDC_DS 0x08 /* Set when a VRAM > SATB DMA transfer is done */ -#define VDC_RR 0x04 /* Set when the current scanline equals the RCR register */ -#define VDC_OR 0x02 /* Set when there are more than 16 sprites on a line */ -#define VDC_CR 0x01 /* Set when sprite #0 overlaps with another sprite */ - -/* Bits in the CR register */ - -#define CR_BB 0x80 /* Background blanking */ -#define CR_SB 0x40 /* Object blanking */ -#define CR_VR 0x08 /* Interrupt on vertical blank enable */ -#define CR_RC 0x04 /* Interrupt on line compare enable */ -#define CR_OV 0x02 /* Interrupt on sprite overflow enable */ -#define CR_CC 0x01 /* Interrupt on sprite #0 collision enable */ - -/* Bits in the DCR regsiter */ - -#define DCR_DSR 0x10 /* VRAM > SATB auto-transfer enable */ -#define DCR_DID 0x08 /* Destination diretion */ -#define DCR_SID 0x04 /* Source direction */ -#define DCR_DVC 0x02 /* VRAM > VRAM EOT interrupt enable */ -#define DCR_DSC 0x01 /* VRAM > SATB EOT interrupt enable */ - -/* just to keep things simple... */ -enum vdc_regs {MAWR = 0, MARR, VxR, reg3, reg4, CR, RCR, BXR, BYR, MWR, HSR, HDR, VPR, VDW, VCR, DCR, SOUR, DESR, LENR, DVSSR }; diff --git a/src/mess/drivers/x1twin.c b/src/mess/drivers/x1twin.c index e88b1ba67b4..d6d54fa3cfc 100644 --- a/src/mess/drivers/x1twin.c +++ b/src/mess/drivers/x1twin.c @@ -17,7 +17,6 @@ #include "includes/x1.h" #include "includes/pce.h" -#include "video/vdc.h" //#include "cpu/h6280/h6280.h" //#include "sound/c6280.h" @@ -59,7 +58,7 @@ ADDRESS_MAP_END static ADDRESS_MAP_START( pce_mem , AS_PROGRAM, 8, x1twin_state ) AM_RANGE( 0x000000, 0x09FFFF) AM_ROM AM_RANGE( 0x1F0000, 0x1F1FFF) AM_RAM AM_MIRROR(0x6000) - AM_RANGE( 0x1FE000, 0x1FE3FF) AM_READWRITE( vdc_0_r, vdc_0_w ) + AM_RANGE( 0x1FE000, 0x1FE3FF) AM_READWRITE( vdc_r, vdc_w ) AM_RANGE( 0x1FE400, 0x1FE7FF) AM_READWRITE( vce_r, vce_w ) AM_RANGE( 0x1FE800, 0x1FEBFF) AM_DEVREADWRITE( "c6280", c6280_device, c6280_r, c6280_w ) AM_RANGE( 0x1FEC00, 0x1FEFFF) AM_READWRITE( h6280_timer_r, h6280_timer_w ) @@ -68,7 +67,7 @@ static ADDRESS_MAP_START( pce_mem , AS_PROGRAM, 8, x1twin_state ) ADDRESS_MAP_END static ADDRESS_MAP_START( pce_io, AS_IO, 8, x1twin_state ) - AM_RANGE( 0x00, 0x03) AM_READWRITE( vdc_0_r, vdc_0_w ) + AM_RANGE( 0x00, 0x03) AM_READWRITE( vdc_r, vdc_w ) ADDRESS_MAP_END #endif @@ -557,7 +556,7 @@ static MACHINE_CONFIG_START( x1twin, x1twin_state ) MCFG_SCREEN_ADD("pce_screen", RASTER) MCFG_SCREEN_REFRESH_RATE(60) MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */ - MCFG_SCREEN_RAW_PARAMS(PCE_MAIN_CLOCK/2, VDC_WPF, 70, 70 + 512 + 32, VDC_LPF, 14, 14+242) + MCFG_SCREEN_RAW_PARAMS(PCE_MAIN_CLOCK/2, HUC6260_WPF, 70, 70 + 512 + 32, HUC6260_LPF, 14, 14+242) MCFG_SCREEN_UPDATE_DRIVER(x1twin_state, screen_update_x1pce) MCFG_MC6845_ADD("crtc", H46505, "x1_screen", (VDP_CLOCK/48), mc6845_intf) //unknown divider