From def3409db00444ff43bf5700c600ae9916a6ba35 Mon Sep 17 00:00:00 2001 From: Angelo Salese Date: Tue, 17 May 2011 18:41:45 +0000 Subject: [PATCH] Removed SMS, nw --- .gitattributes | 5 - src/mame/drivers/segasms.c | 783 ------------- src/mame/includes/segasms.h | 183 ---- src/mame/machine/segasms.c | 2053 ----------------------------------- src/mame/mame.mak | 3 - src/mame/video/smsvdp.c | 1530 -------------------------- src/mame/video/smsvdp.h | 86 -- 7 files changed, 4643 deletions(-) delete mode 100644 src/mame/drivers/segasms.c delete mode 100644 src/mame/includes/segasms.h delete mode 100644 src/mame/machine/segasms.c delete mode 100644 src/mame/video/smsvdp.c delete mode 100644 src/mame/video/smsvdp.h diff --git a/.gitattributes b/.gitattributes index 1357ec415ba..6371c52fef4 100644 --- a/.gitattributes +++ b/.gitattributes @@ -2556,7 +2556,6 @@ src/mame/drivers/segas16b.c svneol=native#text/plain src/mame/drivers/segas18.c svneol=native#text/plain src/mame/drivers/segas24.c svneol=native#text/plain src/mame/drivers/segas32.c svneol=native#text/plain -src/mame/drivers/segasms.c svneol=native#text/plain src/mame/drivers/segaxbd.c svneol=native#text/plain src/mame/drivers/segaybd.c svneol=native#text/plain src/mame/drivers/seibuspi.c svneol=native#text/plain @@ -3347,7 +3346,6 @@ src/mame/includes/segamsys.h svneol=native#text/plain src/mame/includes/segas16.h svneol=native#text/plain src/mame/includes/segas24.h svneol=native#text/plain src/mame/includes/segas32.h svneol=native#text/plain -src/mame/includes/segasms.h svneol=native#text/plain src/mame/includes/sei_crtc.h svneol=native#text/plain src/mame/includes/seibuspi.h svneol=native#text/plain src/mame/includes/seicross.h svneol=native#text/plain @@ -3875,7 +3873,6 @@ src/mame/machine/segaic16.c svneol=native#text/plain src/mame/machine/segaic16.h svneol=native#text/plain src/mame/machine/segamsys.c svneol=native#text/plain src/mame/machine/segas32.c svneol=native#text/plain -src/mame/machine/segasms.c svneol=native#text/plain src/mame/machine/seibuspi.c svneol=native#text/plain src/mame/machine/seibuspi.h svneol=native#text/plain src/mame/machine/seicop.c svneol=native#text/plain @@ -4498,8 +4495,6 @@ src/mame/video/skykid.c svneol=native#text/plain src/mame/video/skyraid.c svneol=native#text/plain src/mame/video/slapfght.c svneol=native#text/plain src/mame/video/slapshot.c svneol=native#text/plain -src/mame/video/smsvdp.c svneol=native#text/plain -src/mame/video/smsvdp.h svneol=native#text/plain src/mame/video/snes.c svneol=native#text/plain src/mame/video/snk.c svneol=native#text/plain src/mame/video/snk6502.c svneol=native#text/plain diff --git a/src/mame/drivers/segasms.c b/src/mame/drivers/segasms.c deleted file mode 100644 index 83487493836..00000000000 --- a/src/mame/drivers/segasms.c +++ /dev/null @@ -1,783 +0,0 @@ -/****************************************************************************** - Contributors: - - Marat Fayzullin (MG source) - Charles Mac Donald - Mathis Rosenhauer - Brad Oliver - Michael Luong - - To do: - - - PSG control for Game Gear (needs custom SN76489 with stereo output for each channel) - - SIO interface for Game Gear (needs netplay, I guess) - - SMS lightgun support - - LCD persistence emulation for GG - - SMS 3D glass support - - The Game Gear SIO and PSG hardware are not emulated but have some - placeholders in 'machine/sms.c' - - Changes: - Apr 02 - Added raster palette effects for SMS & GG (ML) - - Added sprite collision (ML) - - Added zoomed sprites (ML) - May 02 - Fixed paging bug (ML) - - Fixed sprite and tile priority bug (ML) - - Fixed bug #66 (ML) - - Fixed bug #78 (ML) - - try to implement LCD persistence emulation for GG (ML) - Jun 10, 02 - Added bios emulation (ML) - Jun 12, 02 - Added PAL & NTSC systems (ML) - Jun 25, 02 - Added border emulation (ML) - Jun 27, 02 - Version bits for Game Gear (bits 6 of port 00) (ML) - Nov-Dec, 05 - Numerous cleanups, fixes, updates (WP) - Mar, 07 - More cleanups, fixes, mapper additions, etc (WP) - -SMS Store Unit memory map for the second CPU: - -0000-3FFF - BIOS -4000-47FF - RAM -8000 - System Control Register (R/W) - Reading: - bit7 - ready (0 = ready, 1 = not ready) - bit6-bit5 - unknown - bit4-bit3 - timer selection bit switches - bit2-bit0 - unknown - Writing: - bit7-bit4 - unknown, maybe led of selected game to set? - bit3 - unknown, 1 seems to be written all the time - bit2 - unknown, 1 seems to be written all the time - bit1 - reset signal for sms cpu, 0 = reset low, 1 = reset high - bit0 - which cpu receives interrupt signals, 0 = sms cpu, 1 = controlling cpu -C000 - Card/Cartridge selction register (W) - bit7-bit4 - slot to select - bit3 - slot type (0 = cartridge, 1 = card ?) - bit2-bit0 - unknown -C400 - ???? (used once) -D800 - Selection buttons #1, 1-8 (R) -DC00 - Selection buttons #2, 9-16 (R) - - ******************************************************************************/ - -#include "emu.h" -#include "cpu/z80/z80.h" -#include "sound/sn76496.h" -#include "sound/2413intf.h" -#include "includes/segasms.h" -#include "video/smsvdp.h" -#include "imagedev/cartslot.h" - -#include "sms1.lh" - -#define MASTER_CLOCK_PAL 53203400 /* This might be a tiny bit too low */ - - -static ADDRESS_MAP_START( sms1_mem, AS_PROGRAM, 8 ) - AM_RANGE(0x0000, 0x03ff) AM_ROMBANK("bank1") /* First 0x0400 part always points to first page */ - AM_RANGE(0x0400, 0x3fff) AM_ROMBANK("bank2") /* switchable rom bank */ - AM_RANGE(0x4000, 0x5fff) AM_ROMBANK("bank3") /* switchable rom bank */ - AM_RANGE(0x6000, 0x7fff) AM_ROMBANK("bank4") /* switchable rom bank */ - AM_RANGE(0x8000, 0x9fff) AM_READ_BANK("bank5") AM_WRITE(sms_cartram_w) /* ROM bank / on-cart RAM */ - AM_RANGE(0xa000, 0xbfff) AM_READ_BANK("bank6") AM_WRITE(sms_cartram2_w) /* ROM bank / on-cart RAM */ - AM_RANGE(0xc000, 0xdff7) AM_MIRROR(0x2000) AM_RAM /* RAM (mirror at 0xE000) */ - AM_RANGE(0xdff8, 0xdfff) AM_RAM /* RAM "underneath" frame registers */ - AM_RANGE(0xfff8, 0xfffb) AM_READWRITE(sms_sscope_r, sms_sscope_w) /* 3-D glasses */ - AM_RANGE(0xfffc, 0xffff) AM_READWRITE(sms_mapper_r, sms_mapper_w) /* Bankswitch control */ -ADDRESS_MAP_END - -static ADDRESS_MAP_START( sms_mem, AS_PROGRAM, 8 ) - AM_RANGE(0x0000, 0x03ff) AM_ROMBANK("bank1") /* First 0x0400 part always points to first page */ - AM_RANGE(0x0400, 0x3fff) AM_ROMBANK("bank2") /* switchable rom bank */ - AM_RANGE(0x4000, 0x5fff) AM_ROMBANK("bank3") /* switchable rom bank */ - AM_RANGE(0x6000, 0x7fff) AM_ROMBANK("bank4") /* switchable rom bank */ - AM_RANGE(0x8000, 0x9fff) AM_READ_BANK("bank5") AM_WRITE(sms_cartram_w) /* ROM bank / on-cart RAM */ - AM_RANGE(0xa000, 0xbfff) AM_READ_BANK("bank6") AM_WRITE(sms_cartram2_w) /* ROM bank / on-cart RAM */ - AM_RANGE(0xc000, 0xdffb) AM_MIRROR(0x2000) AM_RAM /* RAM (mirror at 0xE000) */ - AM_RANGE(0xdffc, 0xdfff) AM_RAM /* RAM "underneath" frame registers */ - AM_RANGE(0xfffc, 0xffff) AM_READWRITE(sms_mapper_r, sms_mapper_w) /* Bankswitch control */ -ADDRESS_MAP_END - -static ADDRESS_MAP_START( sms_store_mem, AS_PROGRAM, 8 ) - AM_RANGE(0x0000, 0x3fff) AM_ROM /* BIOS */ - AM_RANGE(0x4000, 0x47ff) AM_RAM /* RAM */ - AM_RANGE(0x6000, 0x7fff) AM_ROMBANK("bank10") /* Cartridge/card peek area */ - AM_RANGE(0x8000, 0x8000) AM_READWRITE(sms_store_control_r, sms_store_control_w) /* Control */ - AM_RANGE(0xc000, 0xc000) AM_READWRITE(sms_store_cart_select_r, sms_store_cart_select_w) /* cartridge/card slot selector */ - AM_RANGE(0xd800, 0xd800) AM_READ(sms_store_select1) /* Game selector port #1 */ - AM_RANGE(0xdc00, 0xdc00) AM_READ(sms_store_select2) /* Game selector port #2 */ -ADDRESS_MAP_END - -static ADDRESS_MAP_START( sms_io, AS_IO, 8 ) - ADDRESS_MAP_GLOBAL_MASK(0xff) - ADDRESS_MAP_UNMAP_HIGH - AM_RANGE(0x00, 0x00) AM_MIRROR(0x3e) AM_WRITE(sms_bios_w) - AM_RANGE(0x01, 0x01) AM_MIRROR(0x3e) AM_WRITE(sms_io_control_w) - AM_RANGE(0x40, 0x7f) AM_READ(sms_count_r) - AM_RANGE(0x40, 0x7f) AM_DEVWRITE("smsiii", sn76496_w) - AM_RANGE(0x80, 0x80) AM_MIRROR(0x3e) AM_DEVREADWRITE("sms_vdp", sms_vdp_data_r, sms_vdp_data_w) - AM_RANGE(0x81, 0x81) AM_MIRROR(0x3e) AM_DEVREADWRITE("sms_vdp", sms_vdp_ctrl_r, sms_vdp_ctrl_w) - AM_RANGE(0xc0, 0xc0) AM_MIRROR(0x1e) AM_READ(sms_input_port_0_r) - AM_RANGE(0xc1, 0xc1) AM_MIRROR(0x1e) AM_READ(sms_input_port_1_r) - AM_RANGE(0xe0, 0xe0) AM_MIRROR(0x0e) AM_READ(sms_input_port_0_r) - AM_RANGE(0xe1, 0xe1) AM_MIRROR(0x0e) AM_READ(sms_input_port_1_r) - AM_RANGE(0xf0, 0xf0) AM_READWRITE(sms_input_port_0_r, sms_ym2413_register_port_0_w) - AM_RANGE(0xf1, 0xf1) AM_READWRITE(sms_input_port_1_r, sms_ym2413_data_port_0_w) - AM_RANGE(0xf2, 0xf2) AM_READWRITE(sms_fm_detect_r, sms_fm_detect_w) - AM_RANGE(0xf3, 0xf3) AM_READ(sms_input_port_1_r) - AM_RANGE(0xf4, 0xf4) AM_MIRROR(0x02) AM_READ(sms_input_port_0_r) - AM_RANGE(0xf5, 0xf5) AM_MIRROR(0x02) AM_READ(sms_input_port_1_r) - AM_RANGE(0xf8, 0xf8) AM_MIRROR(0x06) AM_READ(sms_input_port_0_r) - AM_RANGE(0xf9, 0xf9) AM_MIRROR(0x06) AM_READ(sms_input_port_1_r) -ADDRESS_MAP_END - -static ADDRESS_MAP_START( gg_io, AS_IO, 8 ) - ADDRESS_MAP_GLOBAL_MASK(0xff) - ADDRESS_MAP_UNMAP_HIGH - AM_RANGE(0x00, 0x00) AM_READ(gg_input_port_2_r) - AM_RANGE(0x01, 0x05) AM_READWRITE(gg_sio_r, gg_sio_w) - AM_RANGE(0x06, 0x06) AM_DEVWRITE("gamegear", sn76496_stereo_w) - AM_RANGE(0x07, 0x07) AM_WRITE(sms_io_control_w) - AM_RANGE(0x08, 0x08) AM_MIRROR(0x06) AM_WRITE(sms_bios_w) - AM_RANGE(0x09, 0x09) AM_MIRROR(0x06) AM_WRITE(sms_io_control_w) - AM_RANGE(0x10, 0x10) AM_MIRROR(0x0e) AM_WRITE(sms_bios_w) - AM_RANGE(0x11, 0x11) AM_MIRROR(0x0e) AM_WRITE(sms_io_control_w) - AM_RANGE(0x20, 0x20) AM_MIRROR(0x1e) AM_WRITE(sms_bios_w) - AM_RANGE(0x21, 0x21) AM_MIRROR(0x1e) AM_WRITE(sms_io_control_w) - AM_RANGE(0x40, 0x7f) AM_READ(sms_count_r) - AM_RANGE(0x40, 0x7f) AM_DEVWRITE("gamegear", sn76496_w) - AM_RANGE(0x80, 0x80) AM_MIRROR(0x3e) AM_DEVREADWRITE("sms_vdp", sms_vdp_data_r, sms_vdp_data_w) - AM_RANGE(0x81, 0x81) AM_MIRROR(0x3e) AM_DEVREADWRITE("sms_vdp", sms_vdp_ctrl_r, sms_vdp_ctrl_w) - AM_RANGE(0xc0, 0xc0) AM_READ_PORT("PORT_DC") - AM_RANGE(0xc1, 0xc1) AM_READ_PORT("PORT_DD") - AM_RANGE(0xdc, 0xdc) AM_READ_PORT("PORT_DC") - AM_RANGE(0xdd, 0xdd) AM_READ_PORT("PORT_DD") -ADDRESS_MAP_END - - -static INPUT_PORTS_START( sms ) - PORT_START("PORT_DC") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_CATEGORY(10) PORT_PLAYER(1) PORT_8WAY - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_CATEGORY(10) PORT_PLAYER(1) PORT_8WAY - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_CATEGORY(10) PORT_PLAYER(1) PORT_8WAY - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_CATEGORY(10) PORT_PLAYER(1) PORT_8WAY - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_CATEGORY(10) PORT_PLAYER(1) - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_CATEGORY(10) PORT_PLAYER(1) - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_CATEGORY(20) PORT_PLAYER(2) PORT_8WAY - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_CATEGORY(20) PORT_PLAYER(2) PORT_8WAY - - PORT_START("PORT_DD") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_CATEGORY(20) PORT_PLAYER(2) PORT_8WAY - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_CATEGORY(20) PORT_PLAYER(2) PORT_8WAY - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_CATEGORY(20) PORT_PLAYER(2) - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_CATEGORY(20) PORT_PLAYER(2) - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED ) /* Software Reset bit */ - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED ) /* Port A TH */ - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) /* Port B TH */ - - PORT_START("PAUSE") - PORT_BIT( 0x7f, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_START ) PORT_NAME(DEF_STR(Pause)) - - PORT_START("LPHASER0") /* Light phaser X - player 1 */ - PORT_BIT( 0xff, 0x80, IPT_LIGHTGUN_X ) PORT_CROSSHAIR( X, 1.0, 0.0, 0 ) PORT_SENSITIVITY(50) PORT_KEYDELTA(15) PORT_CATEGORY(11) PORT_PLAYER(1) PORT_CHANGED(lgun1_changed, NULL) - - PORT_START("LPHASER1") /* Light phaser Y - player 1 */ - PORT_BIT( 0xff, 0x80, IPT_LIGHTGUN_Y ) PORT_CROSSHAIR( Y, 1.0, 0.0, 0 ) PORT_SENSITIVITY(50) PORT_KEYDELTA(15) PORT_CATEGORY(11) PORT_PLAYER(1) PORT_CHANGED(lgun1_changed, NULL) - - PORT_START("LPHASER2") /* Light phaser X - player 2 */ - PORT_BIT( 0xff, 0x80, IPT_LIGHTGUN_X ) PORT_CROSSHAIR( X, 1.0, 0.0, 0 ) PORT_SENSITIVITY(50) PORT_KEYDELTA(15) PORT_CATEGORY(21) PORT_PLAYER(2) PORT_CHANGED(lgun2_changed, NULL) - - PORT_START("LPHASER3") /* Light phaser Y - player 2 */ - PORT_BIT( 0xff, 0x80, IPT_LIGHTGUN_Y ) PORT_CROSSHAIR( Y, 1.0, 0.0, 0 ) PORT_SENSITIVITY(50) PORT_KEYDELTA(25) PORT_CATEGORY(21) PORT_PLAYER(2) PORT_CHANGED(lgun2_changed, NULL) - - PORT_START("RFU") /* Rapid Fire Unit */ - PORT_CONFNAME( 0x03, 0x00, "Rapid Fire Unit - Player 1" ) - PORT_CONFSETTING( 0x00, DEF_STR( Off ) ) - PORT_CONFSETTING( 0x01, "Button A" ) - PORT_CONFSETTING( 0x02, "Button B" ) - PORT_CONFSETTING( 0x03, "Button A + B" ) - PORT_CONFNAME( 0x0c, 0x00, "Rapid Fire Unit - Player 2" ) - PORT_CONFSETTING( 0x00, DEF_STR( Off ) ) - PORT_CONFSETTING( 0x04, "Button A" ) - PORT_CONFSETTING( 0x08, "Button B" ) - PORT_CONFSETTING( 0x0c, "Button A + B" ) - - PORT_START("PADDLE0") /* Paddle player 1 */ - PORT_BIT( 0xff, 0x80, IPT_PADDLE) PORT_SENSITIVITY(40) PORT_KEYDELTA(20) PORT_CENTERDELTA(0) PORT_MINMAX(0,255) PORT_CATEGORY(12) PORT_PLAYER(1) - - PORT_START("PADDLE1") /* Paddle player 2 */ - PORT_BIT( 0xff, 0x80, IPT_PADDLE) PORT_SENSITIVITY(40) PORT_KEYDELTA(20) PORT_CENTERDELTA(0) PORT_MINMAX(0,255) PORT_CATEGORY(22) PORT_PLAYER(2) - - PORT_START("CTRLIPT") /* Light Phaser and Paddle Control buttons */ - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_CATEGORY(11) PORT_PLAYER(1) - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_CATEGORY(12) PORT_PLAYER(1) - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_CATEGORY(13) PORT_PLAYER(1) - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_CATEGORY(13) PORT_PLAYER(1) - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_CATEGORY(21) PORT_PLAYER(2) - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_CATEGORY(22) PORT_PLAYER(2) - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_CATEGORY(23) PORT_PLAYER(2) - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_CATEGORY(23) PORT_PLAYER(2) - - PORT_START("CTRLSEL") /* Controller selection */ - PORT_CATEGORY_CLASS( 0x0f, 0x00, "Player 1 Controller" ) - PORT_CATEGORY_ITEM( 0x00, DEF_STR( Joystick ), 10 ) - PORT_CATEGORY_ITEM( 0x01, "Light Phaser", 11 ) - PORT_CATEGORY_ITEM( 0x02, "Sega Paddle Control", 12 ) - PORT_CATEGORY_ITEM( 0x03, "Sega Sports Pad", 13 ) - PORT_CATEGORY_CLASS( 0xf0, 0x00, "Player 2 Controller" ) - PORT_CATEGORY_ITEM( 0x00, DEF_STR( Joystick ), 20 ) - PORT_CATEGORY_ITEM( 0x10, "Light Phaser", 21 ) - PORT_CATEGORY_ITEM( 0x20, "Sega Paddle Control", 22 ) - PORT_CATEGORY_ITEM( 0x30, "Sega Sports Pad", 23 ) - - PORT_START("SPORT0") /* Player 1 Sports Pad X axis */ - PORT_BIT( 0xff, 0x00, IPT_TRACKBALL_X ) PORT_SENSITIVITY(50) PORT_KEYDELTA(40) PORT_RESET PORT_REVERSE PORT_CATEGORY(13) PORT_PLAYER(1) - - PORT_START("SPORT1") /* Player 1 Sports Pad Y axis */ - PORT_BIT( 0xff, 0x00, IPT_TRACKBALL_Y ) PORT_SENSITIVITY(50) PORT_KEYDELTA(40) PORT_RESET PORT_REVERSE PORT_CATEGORY(13) PORT_PLAYER(1) - - PORT_START("SPORT2") /* Player 2 Sports Pad X axis */ - PORT_BIT( 0xff, 0x00, IPT_TRACKBALL_X ) PORT_SENSITIVITY(50) PORT_KEYDELTA(40) PORT_RESET PORT_REVERSE PORT_CATEGORY(23) PORT_PLAYER(2) - - PORT_START("SPORT3") /* Player 2 Sports Pad Y axis */ - PORT_BIT( 0xff, 0x00, IPT_TRACKBALL_Y ) PORT_SENSITIVITY(50) PORT_KEYDELTA(40) PORT_RESET PORT_REVERSE PORT_CATEGORY(23) PORT_PLAYER(2) -INPUT_PORTS_END - -static INPUT_PORTS_START( sms1 ) - PORT_INCLUDE( sms ) - - PORT_START("RESET") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_SERVICE1 ) PORT_NAME("Reset Button") - - PORT_START("SEGASCOPE") - PORT_CONFNAME( 0x01, 0x00, "SegaScope (3-D Glasses)" ) - PORT_CONFSETTING( 0x00, DEF_STR( Off ) ) - PORT_CONFSETTING( 0x01, DEF_STR( On ) ) - - PORT_START("SSCOPE_BINOCULAR") - PORT_CONFNAME( 0x03, 0x00, "SegaScope - Binocular Hack" ) PORT_CONDITION("SEGASCOPE", 0x01, PORTCOND_EQUALS, 0x01) - PORT_CONFSETTING( 0x00, DEF_STR( Off ) ) - PORT_CONFSETTING( 0x01, "Left Lens" ) - PORT_CONFSETTING( 0x02, "Right Lens" ) - PORT_CONFSETTING( 0x03, "Both Lens" ) - PORT_BIT( 0x03, 0x00, IPT_UNUSED ) PORT_CONDITION("SEGASCOPE", 0x01, PORTCOND_EQUALS, 0x00) -INPUT_PORTS_END - -static INPUT_PORTS_START( smsj ) - PORT_INCLUDE( sms1 ) - - PORT_START("TVDRAW") - PORT_CONFNAME( 0x01, 0x00, "Terebi Oekaki Graphics Tablet" ) - PORT_CONFSETTING( 0x00, DEF_STR( Off ) ) - PORT_CONFSETTING( 0x01, DEF_STR( On ) ) - - PORT_START("TVDRAW_X") - PORT_BIT( 0xff, 0x80, IPT_LIGHTGUN_X ) PORT_NAME("Tablet - X Axis") PORT_CROSSHAIR(X, 1.0, 0.0, 0) PORT_SENSITIVITY(50) PORT_KEYDELTA(10) PORT_PLAYER(1) - PORT_CONDITION("TVDRAW", 0x01, PORTCOND_EQUALS, 0x01) - - PORT_START("TVDRAW_Y") - PORT_BIT( 0xff, 0x60, IPT_LIGHTGUN_Y ) PORT_NAME("Tablet - Y Axis") PORT_CROSSHAIR(Y, 1.0, 0.0, 0) PORT_MINMAX(0, 191) PORT_SENSITIVITY(50) PORT_KEYDELTA(10) PORT_PLAYER(1) - PORT_CONDITION("TVDRAW", 0x01, PORTCOND_EQUALS, 0x01) - - PORT_START("TVDRAW_PEN") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_NAME("Tablet - Pen") PORT_CONDITION("TVDRAW", 0x01, PORTCOND_EQUALS, 0x01) -INPUT_PORTS_END - -static INPUT_PORTS_START( gg ) - PORT_START("PORT_DC") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(1) PORT_8WAY - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(1) PORT_8WAY - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(1) PORT_8WAY - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(1) PORT_8WAY - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1) - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1) - PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED ) - - PORT_START("PORT_DD") - PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED ) - - PORT_START("START") - PORT_BIT( 0x7f, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_START ) PORT_NAME("Start") /* Game Gear START */ -INPUT_PORTS_END - -static PALETTE_INIT( sms ) -{ - int i; - for (i = 0; i < 64; i++) - { - int r = i & 0x03; - int g = (i & 0x0c) >> 2; - int b = (i & 0x30) >> 4; - palette_set_color_rgb(machine, i, r << 6, g << 6, b << 6); - } - /* TMS9918 palette */ - palette_set_color_rgb(machine, 64+ 0, 0, 0, 0); - palette_set_color_rgb(machine, 64+ 1, 0, 0, 0); - palette_set_color_rgb(machine, 64+ 2, 33, 200, 66); - palette_set_color_rgb(machine, 64+ 3, 94, 220, 120); - palette_set_color_rgb(machine, 64+ 4, 84, 85, 237); - palette_set_color_rgb(machine, 64+ 5, 125, 118, 252); - palette_set_color_rgb(machine, 64+ 6, 212, 82, 77); - palette_set_color_rgb(machine, 64+ 7, 66, 235, 245); - palette_set_color_rgb(machine, 64+ 8, 252, 85, 84); - palette_set_color_rgb(machine, 64+ 9, 255, 121, 120); - palette_set_color_rgb(machine, 64+10, 212, 193, 84); - palette_set_color_rgb(machine, 64+11, 230, 206, 128); - palette_set_color_rgb(machine, 64+12, 33, 176, 59); - palette_set_color_rgb(machine, 64+13, 201, 91, 186); - palette_set_color_rgb(machine, 64+14, 204, 204, 204); - palette_set_color_rgb(machine, 64+15, 255, 255, 255); -} - -static PALETTE_INIT( gamegear ) -{ - int i; - for (i = 0; i < 4096; i++) - { - int r = i & 0x000f; - int g = (i & 0x00f0) >> 4; - int b = (i & 0x0f00) >> 8; - palette_set_color_rgb(machine, i, r << 4, g << 4, b << 4); - } -} - - - -static void sms_int_callback( running_machine &machine, int state ) -{ - cputag_set_input_line(machine, "maincpu", 0, state); -} - -static const smsvdp_interface _315_5124_intf = -{ - MODEL_315_5124, - sms_int_callback, - sms_pause_callback -}; - -static const smsvdp_interface _315_5246_intf = -{ - MODEL_315_5246, - sms_int_callback, - sms_pause_callback -}; - -static const smsvdp_interface _315_5378_intf = -{ - MODEL_315_5378, - sms_int_callback, - sms_pause_callback -}; - -static const smsvdp_interface sms_store_intf = -{ - MODEL_315_5124, - sms_store_int_callback, - sms_pause_callback -}; - -static MACHINE_CONFIG_FRAGMENT( sms_cartslot ) - MCFG_CARTSLOT_ADD("cart1") - MCFG_CARTSLOT_EXTENSION_LIST("sms,bin") - MCFG_CARTSLOT_NOT_MANDATORY - MCFG_CARTSLOT_INTERFACE("sms_cart") - MCFG_CARTSLOT_START(sms_cart) - MCFG_CARTSLOT_LOAD(sms_cart) - - MCFG_SOFTWARE_LIST_ADD("cart_list","sms") -MACHINE_CONFIG_END - -static MACHINE_CONFIG_FRAGMENT( gg_cartslot ) - MCFG_CARTSLOT_ADD("cart1") - MCFG_CARTSLOT_EXTENSION_LIST("gg,bin") - MCFG_CARTSLOT_MANDATORY - MCFG_CARTSLOT_INTERFACE("gamegear_cart") - MCFG_CARTSLOT_START(sms_cart) - MCFG_CARTSLOT_LOAD(sms_cart) - - MCFG_SOFTWARE_LIST_ADD("cart_list","gamegear") -MACHINE_CONFIG_END - -static MACHINE_CONFIG_START( sms_ntsc_base, sms_state ) - /* basic machine hardware */ - MCFG_CPU_ADD("maincpu", Z80, XTAL_53_693175MHz/15) - MCFG_CPU_PROGRAM_MAP(sms_mem) - MCFG_CPU_IO_MAP(sms_io) - - MCFG_QUANTUM_TIME(attotime::from_hz(60)) - - MCFG_MACHINE_START(sms) - MCFG_MACHINE_RESET(sms) - - /* sound hardware */ - MCFG_SPEAKER_STANDARD_MONO("mono") - MCFG_SOUND_ADD("smsiii", SMSIII, XTAL_53_693175MHz/15) - MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00) - - MCFG_FRAGMENT_ADD( sms_cartslot ) -MACHINE_CONFIG_END - -static MACHINE_CONFIG_DERIVED( sms2_ntsc, sms_ntsc_base ) - /* video hardware */ - MCFG_SCREEN_ADD("screen", RASTER) - MCFG_SCREEN_FORMAT(BITMAP_FORMAT_RGB32) - MCFG_SCREEN_RAW_PARAMS(XTAL_53_693175MHz/10, SMS_X_PIXELS, LBORDER_START + LBORDER_X_PIXELS - 2, LBORDER_START + LBORDER_X_PIXELS + 256 + 10, NTSC_Y_PIXELS, TBORDER_START + NTSC_224_TBORDER_Y_PIXELS, TBORDER_START + NTSC_224_TBORDER_Y_PIXELS + 224) - MCFG_SCREEN_UPDATE(sms) - - MCFG_PALETTE_LENGTH(64+16) - MCFG_PALETTE_INIT(sms) - - MCFG_SMSVDP_ADD("sms_vdp", _315_5246_intf) -MACHINE_CONFIG_END - -static MACHINE_CONFIG_DERIVED( sms1_ntsc, sms_ntsc_base ) - - MCFG_CPU_MODIFY("maincpu") - MCFG_CPU_PROGRAM_MAP(sms1_mem) // This adds the SegaScope handlers for 3-D glasses - MCFG_CPU_IO_MAP(sms_io) - - /* video hardware */ - MCFG_SCREEN_ADD("screen", RASTER) - MCFG_SCREEN_FORMAT(BITMAP_FORMAT_RGB32) - MCFG_SCREEN_RAW_PARAMS(XTAL_53_693175MHz/10, SMS_X_PIXELS, LBORDER_START + LBORDER_X_PIXELS - 2, LBORDER_START + LBORDER_X_PIXELS + 256 + 10, NTSC_Y_PIXELS, TBORDER_START + NTSC_224_TBORDER_Y_PIXELS, TBORDER_START + NTSC_224_TBORDER_Y_PIXELS + 224) - MCFG_SCREEN_UPDATE(sms1) - - MCFG_SCREEN_ADD("left_lcd", LCD) // This is needed for SegaScope Left LCD - MCFG_SCREEN_FORMAT(BITMAP_FORMAT_RGB32) - MCFG_SCREEN_RAW_PARAMS(XTAL_53_693175MHz/10, SMS_X_PIXELS, LBORDER_START + LBORDER_X_PIXELS - 2, LBORDER_START + LBORDER_X_PIXELS + 256 + 10, NTSC_Y_PIXELS, TBORDER_START + NTSC_224_TBORDER_Y_PIXELS, TBORDER_START + NTSC_224_TBORDER_Y_PIXELS + 224) - MCFG_SCREEN_UPDATE(sms1) - - MCFG_SCREEN_ADD("right_lcd", LCD) // This is needed for SegaScope Right LCD - MCFG_SCREEN_FORMAT(BITMAP_FORMAT_RGB32) - MCFG_SCREEN_RAW_PARAMS(XTAL_53_693175MHz/10, SMS_X_PIXELS, LBORDER_START + LBORDER_X_PIXELS - 2, LBORDER_START + LBORDER_X_PIXELS + 256 + 10, NTSC_Y_PIXELS, TBORDER_START + NTSC_224_TBORDER_Y_PIXELS, TBORDER_START + NTSC_224_TBORDER_Y_PIXELS + 224) - MCFG_SCREEN_UPDATE(sms1) - - MCFG_DEFAULT_LAYOUT(layout_sms1) - - MCFG_PALETTE_LENGTH(64+16) - MCFG_PALETTE_INIT(sms) - - MCFG_VIDEO_START(sms1) - - MCFG_SMSVDP_ADD("sms_vdp", _315_5124_intf) -MACHINE_CONFIG_END - -#define MCFG_SMSSDISP_CARTSLOT_ADD(_tag) \ - MCFG_CARTSLOT_ADD(_tag) \ - MCFG_CARTSLOT_EXTENSION_LIST("sms,bin") \ - MCFG_CARTSLOT_NOT_MANDATORY \ - MCFG_CARTSLOT_INTERFACE("sms_cart") \ - MCFG_CARTSLOT_START(sms_cart) \ - MCFG_CARTSLOT_LOAD(sms_cart) - -static MACHINE_CONFIG_DERIVED( sms_sdisp, sms2_ntsc ) - - MCFG_DEVICE_REMOVE("sms_vdp") - MCFG_SMSVDP_ADD("sms_vdp", sms_store_intf) - - MCFG_CPU_ADD("control", Z80, XTAL_53_693175MHz/15) - MCFG_CPU_PROGRAM_MAP(sms_store_mem) - /* Both CPUs seem to communicate with the VDP etc? */ - MCFG_CPU_IO_MAP(sms_io) - - MCFG_CARTSLOT_MODIFY("cart1") - MCFG_CARTSLOT_EXTENSION_LIST("sms,bin") - MCFG_CARTSLOT_MANDATORY - MCFG_CARTSLOT_INTERFACE("sms_cart") - MCFG_CARTSLOT_START(sms_cart) - MCFG_CARTSLOT_LOAD(sms_cart) - - MCFG_SMSSDISP_CARTSLOT_ADD("cart2") - MCFG_SMSSDISP_CARTSLOT_ADD("cart3") - MCFG_SMSSDISP_CARTSLOT_ADD("cart4") - MCFG_SMSSDISP_CARTSLOT_ADD("cart5") - MCFG_SMSSDISP_CARTSLOT_ADD("cart6") - MCFG_SMSSDISP_CARTSLOT_ADD("cart7") - MCFG_SMSSDISP_CARTSLOT_ADD("cart8") - MCFG_SMSSDISP_CARTSLOT_ADD("cart9") - MCFG_SMSSDISP_CARTSLOT_ADD("cart10") - MCFG_SMSSDISP_CARTSLOT_ADD("cart11") - MCFG_SMSSDISP_CARTSLOT_ADD("cart12") - MCFG_SMSSDISP_CARTSLOT_ADD("cart13") - MCFG_SMSSDISP_CARTSLOT_ADD("cart14") - MCFG_SMSSDISP_CARTSLOT_ADD("cart15") - MCFG_SMSSDISP_CARTSLOT_ADD("cart16") -MACHINE_CONFIG_END - -static MACHINE_CONFIG_START( sms_pal_base, sms_state ) - /* basic machine hardware */ - MCFG_CPU_ADD("maincpu", Z80, MASTER_CLOCK_PAL/15) - MCFG_CPU_PROGRAM_MAP(sms_mem) - MCFG_CPU_IO_MAP(sms_io) - - MCFG_QUANTUM_TIME(attotime::from_hz(60)) - - MCFG_MACHINE_START(sms) - MCFG_MACHINE_RESET(sms) - - /* sound hardware */ - MCFG_SPEAKER_STANDARD_MONO("mono") - MCFG_SOUND_ADD("smsiii", SMSIII, MASTER_CLOCK_PAL/15) - MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00) - - MCFG_FRAGMENT_ADD( sms_cartslot ) -MACHINE_CONFIG_END - -static MACHINE_CONFIG_DERIVED( sms2_pal, sms_pal_base ) - - /* video hardware */ - MCFG_SCREEN_ADD("screen", RASTER) - MCFG_SCREEN_FORMAT(BITMAP_FORMAT_RGB32) - MCFG_SCREEN_RAW_PARAMS(MASTER_CLOCK_PAL/10, SMS_X_PIXELS, LBORDER_START + LBORDER_X_PIXELS - 2, LBORDER_START + LBORDER_X_PIXELS + 256 + 10, PAL_Y_PIXELS, TBORDER_START + PAL_240_TBORDER_Y_PIXELS, TBORDER_START + PAL_240_TBORDER_Y_PIXELS + 240) - MCFG_SCREEN_UPDATE(sms) - - MCFG_PALETTE_LENGTH(64+16) - MCFG_PALETTE_INIT(sms) - - MCFG_SMSVDP_ADD("sms_vdp", _315_5246_intf) -MACHINE_CONFIG_END - -static MACHINE_CONFIG_DERIVED( sms1_pal, sms_pal_base ) - - MCFG_CPU_MODIFY("maincpu") - MCFG_CPU_PROGRAM_MAP(sms1_mem) // This adds the SegaScope handlers for 3-D glasses - MCFG_CPU_IO_MAP(sms_io) - - /* video hardware */ - MCFG_SCREEN_ADD("screen", RASTER) - MCFG_SCREEN_FORMAT(BITMAP_FORMAT_RGB32) - MCFG_SCREEN_RAW_PARAMS(MASTER_CLOCK_PAL/10, SMS_X_PIXELS, LBORDER_START + LBORDER_X_PIXELS - 2, LBORDER_START + LBORDER_X_PIXELS + 256 + 10, PAL_Y_PIXELS, TBORDER_START + PAL_240_TBORDER_Y_PIXELS, TBORDER_START + PAL_240_TBORDER_Y_PIXELS + 240) - MCFG_SCREEN_UPDATE(sms1) - - MCFG_SCREEN_ADD("left_lcd", LCD) // This is needed for SegaScope Left LCD - MCFG_SCREEN_FORMAT(BITMAP_FORMAT_RGB32) - MCFG_SCREEN_RAW_PARAMS(MASTER_CLOCK_PAL/10, SMS_X_PIXELS, LBORDER_START + LBORDER_X_PIXELS - 2, LBORDER_START + LBORDER_X_PIXELS + 256 + 10, PAL_Y_PIXELS, TBORDER_START + PAL_240_TBORDER_Y_PIXELS, TBORDER_START + PAL_240_TBORDER_Y_PIXELS + 240) - MCFG_SCREEN_UPDATE(sms1) - - MCFG_SCREEN_ADD("right_lcd", LCD) // This is needed for SegaScope Right LCD - MCFG_SCREEN_FORMAT(BITMAP_FORMAT_RGB32) - MCFG_SCREEN_RAW_PARAMS(MASTER_CLOCK_PAL/10, SMS_X_PIXELS, LBORDER_START + LBORDER_X_PIXELS - 2, LBORDER_START + LBORDER_X_PIXELS + 256 + 10, PAL_Y_PIXELS, TBORDER_START + PAL_240_TBORDER_Y_PIXELS, TBORDER_START + PAL_240_TBORDER_Y_PIXELS + 240) - MCFG_SCREEN_UPDATE(sms1) - - MCFG_PALETTE_LENGTH(64+16) - MCFG_PALETTE_INIT(sms) - - MCFG_DEFAULT_LAYOUT(layout_sms1) - - MCFG_SMSVDP_ADD("sms_vdp", _315_5124_intf) -MACHINE_CONFIG_END - -static MACHINE_CONFIG_DERIVED( sms_fm, sms1_ntsc ) - - MCFG_SOUND_ADD("ym2413", YM2413, XTAL_53_693175MHz/15) - MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00) -MACHINE_CONFIG_END - -static MACHINE_CONFIG_DERIVED( sg1000m3, sms_fm ) - - MCFG_CARTSLOT_MODIFY("cart1") - MCFG_CARTSLOT_EXTENSION_LIST("sms,bin,sg") - MCFG_CARTSLOT_MANDATORY - MCFG_CARTSLOT_START(sms_cart) - MCFG_CARTSLOT_LOAD(sms_cart) -MACHINE_CONFIG_END - -static MACHINE_CONFIG_DERIVED( sms2_fm, sms2_ntsc ) - - MCFG_SOUND_ADD("ym2413", YM2413, XTAL_53_693175MHz/15) - MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00) -MACHINE_CONFIG_END - -static MACHINE_CONFIG_START( gamegear, sms_state ) - /* basic machine hardware */ - MCFG_CPU_ADD("maincpu", Z80, XTAL_53_693175MHz/15) - MCFG_CPU_PROGRAM_MAP(sms_mem) - MCFG_CPU_IO_MAP(gg_io) - - MCFG_QUANTUM_TIME(attotime::from_hz(60)) - - MCFG_MACHINE_START(sms) - MCFG_MACHINE_RESET(sms) - - /* video hardware */ - MCFG_SCREEN_ADD("screen", LCD) - MCFG_SCREEN_FORMAT(BITMAP_FORMAT_RGB32) - MCFG_SCREEN_RAW_PARAMS(XTAL_53_693175MHz/10, SMS_X_PIXELS, LBORDER_START + LBORDER_X_PIXELS + 6*8, LBORDER_START + LBORDER_X_PIXELS + 26*8, NTSC_Y_PIXELS, TBORDER_START + NTSC_192_TBORDER_Y_PIXELS + 3*8, TBORDER_START + NTSC_192_TBORDER_Y_PIXELS + 21*8 ) - MCFG_SCREEN_UPDATE(gamegear) - - MCFG_PALETTE_LENGTH(4096) - MCFG_PALETTE_INIT(gamegear) - - MCFG_VIDEO_START(gamegear) - - MCFG_SMSVDP_ADD("sms_vdp", _315_5378_intf) - - /* sound hardware */ - MCFG_SPEAKER_STANDARD_STEREO("lspeaker","rspeaker") - MCFG_SOUND_ADD("gamegear", GAMEGEAR, XTAL_53_693175MHz/15) - MCFG_SOUND_ROUTE(0, "lspeaker", 1.00) - MCFG_SOUND_ROUTE(1, "rspeaker", 1.00) - - /* cartridge */ - MCFG_FRAGMENT_ADD( gg_cartslot ) -MACHINE_CONFIG_END - - -ROM_START(sms1) - ROM_REGION(0x4000, "maincpu", 0) - ROM_FILL(0x0000, 0x4000, 0xff) - - ROM_REGION(0x20000, "user1", 0) - ROM_SYSTEM_BIOS( 0, "bios13", "US/European BIOS v1.3 (1986)" ) - ROMX_LOAD("bios13fx.rom", 0x0000, 0x2000, CRC(0072ED54) SHA1(c315672807d8ddb8d91443729405c766dd95cae7), ROM_BIOS(1)) - ROM_SYSTEM_BIOS( 1, "hangonsh", "US/European BIOS v2.4 with Hang On and Safari Hunt (1988)" ) - ROMX_LOAD("hshbios.rom", 0x0000, 0x20000, CRC(91E93385) SHA1(9e179392cd416af14024d8f31c981d9ee9a64517), ROM_BIOS(2)) - ROM_SYSTEM_BIOS( 2, "hangon", "US/European BIOS v3.4 with Hang On (1988)" ) - ROMX_LOAD("hangbios.rom", 0x0000, 0x20000, CRC(8EDF7AC6) SHA1(51fd6d7990f62cd9d18c9ecfc62ed7936169107e), ROM_BIOS(3)) - ROM_SYSTEM_BIOS( 3, "missiled", "US/European BIOS v4.4 with Missile Defense 3D (1988)" ) - ROMX_LOAD("missiled.rom", 0x0000, 0x20000, CRC(E79BB689) SHA1(aa92ae576ca670b00855e278378d89e9f85e0351), ROM_BIOS(4)) - ROM_SYSTEM_BIOS( 4, "proto", "US Master System Prototype BIOS" ) - ROMX_LOAD("m404prot.rom", 0x0000, 0x2000, CRC(1a15dfcc) SHA1(4a06c8e66261611dce0305217c42138b71331701), ROM_BIOS(5)) -ROM_END - -ROM_START(sms) - ROM_REGION(0x4000, "maincpu", 0) - ROM_FILL(0x0000, 0x4000, 0xff) - - ROM_REGION(0x20000, "user1", 0) - ROM_SYSTEM_BIOS( 0, "alexkidd", "US/European BIOS with Alex Kidd in Miracle World (1990)" ) - ROMX_LOAD("akbios.rom", 0x0000, 0x20000, CRC(CF4A09EA) SHA1(3af7b66248d34eb26da40c92bf2fa4c73a46a051), ROM_BIOS(1)) -ROM_END - -ROM_START(smssdisp) - ROM_REGION(0x4000, "maincpu", 0) - ROM_FILL(0x0000, 0x4000, 0x00) - - ROM_REGION(0x4000, "user1", 0) - ROM_FILL(0x0000, 0x4000, 0xff) - - ROM_REGION(0x4000, "control", 0) - ROM_LOAD("smssdisp.rom", 0x0000, 0x4000, CRC(ee2c29ba) SHA1(fc465122134d95363112eb51b9ab71db3576cefd)) -ROM_END - -ROM_START(sms1pal) - ROM_REGION(0x4000, "maincpu", 0) - ROM_FILL(0x0000, 0x4000, 0xff) - - ROM_REGION(0x20000, "user1", 0) - ROM_SYSTEM_BIOS( 0, "bios13", "US/European BIOS v1.3 (1986)" ) - ROMX_LOAD("bios13fx.rom", 0x0000, 0x2000, CRC(0072ED54) SHA1(c315672807d8ddb8d91443729405c766dd95cae7), ROM_BIOS(1)) - ROM_SYSTEM_BIOS( 1, "hangonsh", "US/European BIOS v2.4 with Hang On and Safari Hunt (1988)" ) - ROMX_LOAD("hshbios.rom", 0x0000, 0x20000, CRC(91E93385) SHA1(9e179392cd416af14024d8f31c981d9ee9a64517), ROM_BIOS(2)) - ROM_SYSTEM_BIOS( 2, "hangon", "Sega Master System - US/European BIOS v3.4 with Hang On (1988)" ) - ROMX_LOAD("hangbios.rom", 0x0000, 0x20000, CRC(8EDF7AC6) SHA1(51fd6d7990f62cd9d18c9ecfc62ed7936169107e), ROM_BIOS(3)) - ROM_SYSTEM_BIOS( 3, "missiled", "US/European BIOS v4.4 with Missile Defense 3D (1988)" ) - ROMX_LOAD("missiled.rom", 0x0000, 0x20000, CRC(E79BB689) SHA1(aa92ae576ca670b00855e278378d89e9f85e0351), ROM_BIOS(4)) -ROM_END - -ROM_START(smspal) - ROM_REGION(0x4000, "maincpu", 0) - ROM_FILL(0x0000, 0x4000, 0xff) - - ROM_REGION(0x40000, "user1", 0) - ROM_SYSTEM_BIOS( 0, "alexkidd", "US/European BIOS with Alex Kidd in Miracle World (1990)" ) - ROMX_LOAD("akbios.rom", 0x0000, 0x20000, CRC(CF4A09EA) SHA1(3af7b66248d34eb26da40c92bf2fa4c73a46a051), ROM_BIOS(1)) - ROM_SYSTEM_BIOS( 1, "sonic", "European/Brazilian BIOS with Sonic the Hedgehog (1991)" ) - ROMX_LOAD("sonbios.rom", 0x0000, 0x40000, CRC(81C3476B) SHA1(6aca0e3dffe461ba1cb11a86cd4caf5b97e1b8df), ROM_BIOS(2)) -ROM_END - -ROM_START(sg1000m3) - ROM_REGION(0x4000, "maincpu", 0) - ROM_FILL(0x0000, 0x4000, 0x00) -ROM_END - -ROM_START(smsj) - ROM_REGION(0x4000, "maincpu", 0) - ROM_FILL(0x0000, 0x4000, 0xff) - - ROM_REGION(0x4000, "user1", 0) - ROM_SYSTEM_BIOS( 0, "jbios21", "Japanese BIOS v2.1 (1987)" ) - ROMX_LOAD("jbios21.rom", 0x0000, 0x2000, CRC(48D44A13) SHA1(a8c1b39a2e41137835eda6a5de6d46dd9fadbaf2), ROM_BIOS(1)) -ROM_END - -ROM_START(sms2kr) - ROM_REGION(0x4000, "maincpu", 0) - ROM_FILL(0x0000, 0x4000, 0xff) - - ROM_REGION(0x20000, "user1", 0) - ROM_SYSTEM_BIOS( 0, "akbioskr", "Samsung Gam*Boy II with Alex Kidd in Miracle World (1990)" ) - ROMX_LOAD("akbioskr.rom", 0x000, 0x20000, CRC(9c5bad91) SHA1(2feafd8f1c40fdf1bd5668f8c5c02e5560945b17), ROM_BIOS(1)) -ROM_END - -ROM_START(gamegear) - ROM_REGION(0x4000, "maincpu", 0) - ROM_FILL(0x0000, 0x4000, 0x00) - - ROM_REGION(0x0400, "user1", 0) - ROM_SYSTEM_BIOS( 0, "none", "No BIOS" ) /* gamegear */ - ROM_SYSTEM_BIOS( 1, "majesco", "Majesco BIOS" ) /* gamg */ - ROMX_LOAD("majbios.rom", 0x0000, 0x0400, CRC(0EBEA9D4) SHA1(914aa165e3d879f060be77870d345b60cfeb4ede), ROM_BIOS(2)) -ROM_END - -#define rom_gamegeaj rom_gamegear - -/*************************************************************************** - - Game driver(s) - - US - - Sega Master System I (sms1) - - prototype bios - 1986 - - without built-in game v1.3 - 1986 - - built-in Hang On/Safari Hunt v2.4 - 1988 - - built-in Hang On v3.4 - 1988 - - built-in Missile Defense 3-D v4.4 - 1988 - - built-in Hang On/Astro Warrior ???? - - Sega Master System II (sms/sms2) - - built-in Alex Kidd in Miracle World - 1990 - - JP - - Sega SG-1000 Mark III (smsm3) - - no bios - - Sega Master System (I) (smsj) - - without built-in game v2.1 - 1987 - - KR - - Sega Master System II (sms2kr) - - built-in Alex Kidd in Miracle World (Korean) - - EU - - Sega Master System I (sms1pal) - - without built-in game v1.3 - 1986 - - built-in Hang On/Safari Hunt v2.4 - 1988 - - built-in Hang On v3.4 - 1988 - - built-in Missile Defense 3-D v4.4 - 1988 - - built-in Hang On/Astro Warrior ???? - - Sega Master System II (sms2pal) - - built-in Alex Kidd in Miracle World - 1990 - - built-in Sonic the Hedgehog - 1991 - - BR - - Sega Master System I - 1987 - - Sega Master System II??? - - Sega Master System III - Tec Toy, 1987 - - Sega Master System Compact - Tec Toy, 1992 - - Sega Master System Girl - Tec Toy, 1992 - -***************************************************************************/ - -/* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME FLAGS */ -CONS( 1984, sg1000m3, sms, 0, sg1000m3, smsj, sg1000m3, "Sega", "SG-1000 Mark III", 0 ) -CONS( 1986, sms1, sms, 0, sms1_ntsc, sms1, sms1, "Sega", "Master System I", 0 ) -CONS( 1986, sms1pal, sms, 0, sms1_pal, sms1, sms1, "Sega", "Master System I (PAL)" , 0 ) -CONS( 1986, smssdisp, sms, 0, sms_sdisp, sms, smssdisp, "Sega", "Master System Store Display Unit", GAME_NOT_WORKING ) -CONS( 1987, smsj, sms, 0, sms_fm, smsj, smsj, "Sega", "Master System (Japan)", 0 ) -CONS( 1990, sms, 0, 0, sms2_ntsc, sms, sms1, "Sega", "Master System II", 0 ) -CONS( 1990, smspal, sms, 0, sms2_pal, sms, sms1, "Sega", "Master System II (PAL)", 0 ) -CONS( 1990, sms2kr, sms, 0, sms2_fm, sms, sms2kr, "Samsung", "Gam*Boy II (Korea)", 0 ) - -CONS( 1990, gamegear, 0, sms, gamegear, gg, gamegear, "Sega", "Game Gear (Europe/America)", 0 ) -CONS( 1990, gamegeaj, gamegear, 0, gamegear, gg, gamegeaj, "Sega", "Game Gear (Japan)", 0 ) diff --git a/src/mame/includes/segasms.h b/src/mame/includes/segasms.h deleted file mode 100644 index 8ec361e0b37..00000000000 --- a/src/mame/includes/segasms.h +++ /dev/null @@ -1,183 +0,0 @@ -/***************************************************************************** - * - * includes/sms.h - * - ****************************************************************************/ - -#ifndef SMS_H_ -#define SMS_H_ - -#define LOG_REG -#define LOG_PAGING -#define LOG_COLOR - -#define NVRAM_SIZE (0x08000) -#define CPU_ADDRESSABLE_SIZE (0x10000) - -#define MAX_CARTRIDGES 16 - -class sms_state : public driver_device -{ -public: - sms_state(const machine_config &mconfig, device_type type, const char *tag) - : driver_device(mconfig, type, tag) { } - - // device_ts - device_t *m_main_cpu; - device_t *m_control_cpu; - device_t *m_vdp; - device_t *m_ym; - device_t *m_main_scr; - device_t *m_left_lcd; - device_t *m_right_lcd; - - UINT8 m_bios_page_count; - UINT8 m_fm_detect; - UINT8 m_ctrl_reg; - int m_paused; - UINT8 m_bios_port; - UINT8 *m_BIOS; - UINT8 *m_mapper_ram; - UINT8 m_mapper[4]; - // we are going to use 1-6, same as bank numbers. Notice, though, that most mappers - // only work on 16K banks and, hence, banks 4-6 are not always directly set - // (they often use bank3 + 0x2000 and bank5 + 0x2000) - UINT8 *m_banking_bios[7]; - UINT8 *m_banking_cart[7]; - UINT8 *m_banking_none[7]; - UINT8 m_gg_sio[5]; - UINT8 m_store_control; - UINT8 m_input_port0; - UINT8 m_input_port1; - - // for gamegear LCD persistence hack - bitmap_t *m_tmp_bitmap; - bitmap_t *m_prev_bitmap; - - // for 3D glass binocular hack - bitmap_t *m_prevleft_bitmap; - bitmap_t *m_prevright_bitmap; - - /* Model identifiers */ - UINT8 m_is_gamegear; - UINT8 m_is_region_japan; - UINT8 m_has_bios_0400; - UINT8 m_has_bios_2000; - UINT8 m_has_bios_full; - UINT8 m_has_bios; - UINT8 m_has_fm; - - /* Data needed for Rapid Fire Unit support */ - emu_timer *m_rapid_fire_timer; - UINT8 m_rapid_fire_state_1; - UINT8 m_rapid_fire_state_2; - - /* Data needed for Paddle Control controller */ - UINT32 m_last_paddle_read_time; - UINT8 m_paddle_read_state; - - /* Data needed for Sports Pad controller */ - UINT32 m_last_sports_pad_time_1; - UINT32 m_last_sports_pad_time_2; - UINT8 m_sports_pad_state_1; - UINT8 m_sports_pad_state_2; - UINT8 m_sports_pad_last_data_1; - UINT8 m_sports_pad_last_data_2; - UINT8 m_sports_pad_1_x; - UINT8 m_sports_pad_1_y; - UINT8 m_sports_pad_2_x; - UINT8 m_sports_pad_2_y; - - /* Data needed for Light Phaser */ - emu_timer *m_lphaser_1_timer; - emu_timer *m_lphaser_2_timer; - UINT8 m_lphaser_1_latch; - UINT8 m_lphaser_2_latch; - int m_lphaser_x_offs; /* Needed to 'calibrate' lphaser; set at cart loading */ - - /* Data needed for SegaScope (3D glasses) */ - UINT8 m_sscope_state; - - /* Data needed for Terebi Oekaki (TV Draw) */ - UINT8 m_tvdraw_data; - - /* Cartridge slot info */ - UINT8 m_current_cartridge; - struct - { - UINT8 *ROM; /* Pointer to ROM image data */ - UINT32 size; /* Size of the ROM image */ - UINT8 features; /* on-cartridge special hardware */ - UINT8 *cartSRAM; /* on-cartridge SRAM */ - UINT8 sram_save; /* should be the contents of the on-cartridge SRAM be saved */ - UINT8 *cartRAM; /* additional on-cartridge RAM (64KB for Ernie Els Golf) */ - UINT32 ram_size; /* size of the on-cartridge RAM */ - UINT8 ram_page; /* currently swapped in cartridge RAM */ - } m_cartridge[MAX_CARTRIDGES]; -}; - - -/*----------- defined in machine/sms.c -----------*/ - -/* Function prototypes */ -WRITE8_HANDLER( sms_cartram_w ); -WRITE8_HANDLER( sms_cartram2_w ); -WRITE8_HANDLER( sms_fm_detect_w ); -READ8_HANDLER( sms_fm_detect_r ); -READ8_HANDLER( sms_input_port_0_r ); -READ8_HANDLER( sms_input_port_1_r ); -WRITE8_HANDLER( sms_ym2413_register_port_0_w ); -WRITE8_HANDLER( sms_ym2413_data_port_0_w ); -WRITE8_HANDLER( sms_io_control_w ); -READ8_HANDLER( sms_count_r ); -WRITE8_HANDLER( sms_sscope_w ); -READ8_HANDLER( sms_sscope_r ); -WRITE8_HANDLER( sms_mapper_w ); -READ8_HANDLER( sms_mapper_r ); -WRITE8_HANDLER( sms_bios_w ); -WRITE8_HANDLER( gg_sio_w ); -READ8_HANDLER( gg_sio_r ); -READ8_HANDLER( gg_input_port_2_r ); - -INPUT_CHANGED( lgun1_changed ); -INPUT_CHANGED( lgun2_changed ); - -void sms_pause_callback( running_machine &machine ); -void sms_store_int_callback( running_machine &machine, int state ); - -DEVICE_START( sms_cart ); -DEVICE_IMAGE_LOAD( sms_cart ); - -MACHINE_START( sms ); -MACHINE_RESET( sms ); - -READ8_HANDLER( sms_store_cart_select_r ); -WRITE8_HANDLER( sms_store_cart_select_w ); -READ8_HANDLER( sms_store_select1 ); -READ8_HANDLER( sms_store_select2 ); -READ8_HANDLER( sms_store_control_r ); -WRITE8_HANDLER( sms_store_control_w ); - -#define IO_EXPANSION (0x80) /* Expansion slot enable (1= disabled, 0= enabled) */ -#define IO_CARTRIDGE (0x40) /* Cartridge slot enable (1= disabled, 0= enabled) */ -#define IO_CARD (0x20) /* Card slot disabled (1= disabled, 0= enabled) */ -#define IO_WORK_RAM (0x10) /* Work RAM disabled (1= disabled, 0= enabled) */ -#define IO_BIOS_ROM (0x08) /* BIOS ROM disabled (1= disabled, 0= enabled) */ -#define IO_CHIP (0x04) /* I/O chip disabled (1= disabled, 0= enabled) */ - - -DRIVER_INIT( sg1000m3 ); -DRIVER_INIT( sms1 ); -DRIVER_INIT( smsj ); -DRIVER_INIT( sms2kr ); -DRIVER_INIT( smssdisp ); -DRIVER_INIT( gamegear ); -DRIVER_INIT( gamegeaj ); - -VIDEO_START( sms1 ); -VIDEO_START( gamegear ); -SCREEN_UPDATE( sms1 ); -SCREEN_UPDATE( sms ); -SCREEN_UPDATE( gamegear ); - -#endif /* SMS_H_ */ diff --git a/src/mame/machine/segasms.c b/src/mame/machine/segasms.c deleted file mode 100644 index 3adb3e09de5..00000000000 --- a/src/mame/machine/segasms.c +++ /dev/null @@ -1,2053 +0,0 @@ -#include "emu.h" -#include "crsshair.h" -#include "image.h" -#include "includes/segasms.h" -#include "video/smsvdp.h" -#include "sound/2413intf.h" -#include "imagedev/cartslot.h" -#include "hashfile.h" - -#define VERBOSE 0 -#define LOG(x) do { if (VERBOSE) logerror x; } while (0) - -#define CF_CODEMASTERS_MAPPER 0x01 -#define CF_KOREAN_MAPPER 0x02 -#define CF_KOREAN_ZEMINA_MAPPER 0x04 -#define CF_KOREAN_NOBANK_MAPPER 0x08 -#define CF_93C46_EEPROM 0x10 -#define CF_ONCART_RAM 0x20 -#define CF_GG_SMS_MODE 0x40 - -#define LGUN_RADIUS 6 -#define LGUN_X_INTERVAL 4 - - -static void setup_rom(address_space *space); - - -static TIMER_CALLBACK( rapid_fire_callback ) -{ - sms_state *state = machine.driver_data(); - state->m_rapid_fire_state_1 ^= 0xff; - state->m_rapid_fire_state_2 ^= 0xff; -} - - -static WRITE8_HANDLER( sms_input_write ) -{ - sms_state *state = space->machine().driver_data(); - - switch (offset) - { - case 0: - switch (input_port_read_safe(space->machine(), "CTRLSEL", 0x00) & 0x0f) - { - case 0x03: /* Sports Pad */ - if (data != state->m_sports_pad_last_data_1) - { - UINT32 cpu_cycles = downcast(&space->device())->total_cycles(); - - state->m_sports_pad_last_data_1 = data; - if (cpu_cycles - state->m_last_sports_pad_time_1 > 512) - { - state->m_sports_pad_state_1 = 3; - state->m_sports_pad_1_x = input_port_read(space->machine(), "SPORT0"); - state->m_sports_pad_1_y = input_port_read(space->machine(), "SPORT1"); - } - state->m_last_sports_pad_time_1 = cpu_cycles; - state->m_sports_pad_state_1 = (state->m_sports_pad_state_1 + 1) & 3; - } - break; - } - break; - - case 1: - switch (input_port_read_safe(space->machine(), "CTRLSEL", 0x00) >> 4) - { - case 0x03: /* Sports Pad */ - if (data != state->m_sports_pad_last_data_2) - { - UINT32 cpu_cycles = downcast(&space->device())->total_cycles(); - - state->m_sports_pad_last_data_2 = data; - if (cpu_cycles - state->m_last_sports_pad_time_2 > 2048) - { - state->m_sports_pad_state_2 = 3; - state->m_sports_pad_2_x = input_port_read(space->machine(), "SPORT2"); - state->m_sports_pad_2_y = input_port_read(space->machine(), "SPORT3"); - } - state->m_last_sports_pad_time_2 = cpu_cycles; - state->m_sports_pad_state_2 = (state->m_sports_pad_state_2 + 1) & 3; - } - break; - } - break; - } -} - -/* FIXME: this function is a hack for Light Phaser emulation. Theoretically - sms_vdp_hcount_latch() should be used instead, but it returns incorrect - position for unknown reason (timing?) */ -static void sms_vdp_hcount_lphaser( running_machine &machine, int hpos ) -{ - sms_state *state = machine.driver_data(); - int hpos_tmp = hpos + state->m_lphaser_x_offs; - UINT8 tmp = ((hpos_tmp - 46) >> 1) & 0xff; - - //printf ("sms_vdp_hcount_lphaser: hpos %3d hpos_tmp %3d => hcount %2X\n", hpos, hpos_tmp, tmp); - sms_vdp_hcount_latch_w(state->m_vdp, 0, tmp); -} - - -/* - Light Phaser (light gun) emulation notes: - - The sensor is activated based on color brightness of some individual - pixels being drawn by the beam, at circular area where the gun is aiming. - - Currently, brightness is calculated based only on single pixels. - - In general, after the trigger is pressed, games draw the next frame using - a light color pattern, to make sure sensor will be activated. If emulation - skips that frame, sensor may stay deactivated. Frameskip set to 0 (no skip) is - recommended to avoid problems. - - When sensor switches from off to on, a value is latched for HCount register - and a flag is set. The emulation uses the flag to avoid sequential latches and - to signal that TH line is activated when the status of the input port is read. - When the status is read, the flag is cleared, or else it is cleared later when - the Pause status is read (end of a frame). This is necessary because the - "Color & Switch Test" ROM only reads the TH bit after the VINT line. - - The gun test of "Color & Switch Test" is an example that requires checks - of sensor status independent of other events, like trigger press or TH bit - reads. Another example is the title screen of "Hang-On & Safari Hunt", where - the game only reads HCount register in a loop, expecting a latch by the gun. - - The whole procedure is managed by a timer callback, that always reschedule - itself to run in some intervals when the beam is at the circular area. -*/ -static int lgun_bright_aim_area( running_machine &machine, emu_timer *timer, int lgun_x, int lgun_y ) -{ - sms_state *state = machine.driver_data(); - const int r_x_r = LGUN_RADIUS * LGUN_RADIUS; - screen_device *screen = machine.first_screen(); - const rectangle &visarea = screen->visible_area(); - int beam_x = screen->hpos(); - int beam_y = screen->vpos(); - int dx, dy; - int result = 0; - int pos_changed = 0; - double dx_circ; - - while (1) - { - dy = abs(beam_y - lgun_y); - - if (dy > LGUN_RADIUS || beam_y < visarea.min_y || beam_y > visarea.max_y) - { - beam_y = lgun_y - LGUN_RADIUS; - if (beam_y < visarea.min_y) - beam_y = visarea.min_y; - dy = abs(beam_y - lgun_y); - pos_changed = 1; - } - /* step 1: r^2 = dx^2 + dy^2 */ - /* step 2: dx^2 = r^2 - dy^2 */ - /* step 3: dx = sqrt(r^2 - dy^2) */ - dx_circ = ceil((float) sqrt((float) (r_x_r - (dy * dy)))); - dx = abs(beam_x - lgun_x); - - if (dx > dx_circ || beam_x < visarea.min_x || beam_x > visarea.max_x) - { - if (beam_x > lgun_x) - { - beam_x = 0; - beam_y++; - continue; - } - beam_x = lgun_x - dx_circ; - if (beam_x < visarea.min_x) - beam_x = visarea.min_x; - pos_changed = 1; - } - - if (!pos_changed) - { - result = sms_vdp_check_brightness(state->m_vdp, beam_x, beam_y); - /* next check at same line */ - beam_x += LGUN_X_INTERVAL; - pos_changed = 1; - } - else - break; - } - timer->adjust(machine.first_screen()->time_until_pos(beam_y, beam_x)); - - return result; -} - -static UINT8 sms_vdp_hcount( running_machine &machine ) -{ - UINT8 tmp; - screen_device *screen = machine.first_screen(); - int hpos = screen->hpos(); - - /* alternative method: pass HCounter test, but some others fail */ - //int hpos_tmp = hpos; - //if ((hpos + 2) % 6 == 0) hpos_tmp--; - //tmp = ((hpos_tmp - 46) >> 1) & 0xff; - - UINT64 calc_cycles; - attotime time_end; - int vpos = screen->vpos(); - int max_hpos = screen->width() - 1; - - if (hpos == max_hpos) - time_end = attotime::zero; - else - time_end = screen->time_until_pos(vpos, max_hpos); - calc_cycles = machine.device("maincpu")->attotime_to_clocks(time_end); - - /* equation got from SMSPower forum, posted by Flubba. */ - tmp = ((590 - (calc_cycles * 3)) / 4) & 0xff; - - //printf ("sms_vdp_hcount: hpos %3d => hcount %2X\n", hpos, tmp); - return tmp; -} - - -static void sms_vdp_hcount_latch( running_machine &machine ) -{ - sms_state *state = machine.driver_data(); - UINT8 value = sms_vdp_hcount(machine); - - sms_vdp_hcount_latch_w(state->m_vdp, 0, value); -} - - -static UINT16 screen_hpos_nonscaled( screen_device *screen, int scaled_hpos ) -{ - const rectangle &visarea = screen->visible_area(); - int offset_x = (scaled_hpos * (visarea.max_x - visarea.min_x)) / 255; - return visarea.min_x + offset_x; -} - - -static UINT16 screen_vpos_nonscaled( screen_device *screen, int scaled_vpos ) -{ - const rectangle &visarea = screen->visible_area(); - int offset_y = (scaled_vpos * (visarea.max_y - visarea.min_y)) / 255; - return visarea.min_y + offset_y; -} - - -static void lphaser1_sensor_check( running_machine &machine ) -{ - sms_state *state = machine.driver_data(); - const int x = screen_hpos_nonscaled(machine.first_screen(), input_port_read(machine, "LPHASER0")); - const int y = screen_vpos_nonscaled(machine.first_screen(), input_port_read(machine, "LPHASER1")); - - if (lgun_bright_aim_area(machine, state->m_lphaser_1_timer, x, y)) - { - if (state->m_lphaser_1_latch == 0) - { - state->m_lphaser_1_latch = 1; - sms_vdp_hcount_lphaser(machine, x); - } - } -} - -static void lphaser2_sensor_check( running_machine &machine ) -{ - sms_state *state = machine.driver_data(); - const int x = screen_hpos_nonscaled(machine.first_screen(), input_port_read(machine, "LPHASER2")); - const int y = screen_vpos_nonscaled(machine.first_screen(), input_port_read(machine, "LPHASER3")); - - if (lgun_bright_aim_area(machine, state->m_lphaser_2_timer, x, y)) - { - if (state->m_lphaser_2_latch == 0) - { - state->m_lphaser_2_latch = 1; - sms_vdp_hcount_lphaser(machine, x); - } - } -} - - -// at each input port read we check if lightguns are enabled in one of the ports: -// if so, we turn on crosshair and the lightgun timer -static TIMER_CALLBACK( lightgun_tick ) -{ - sms_state *state = machine.driver_data(); - - if ((input_port_read_safe(machine, "CTRLSEL", 0x00) & 0x0f) == 0x01) - { - /* enable crosshair */ - crosshair_set_screen(machine, 0, CROSSHAIR_SCREEN_ALL); - if (!state->m_lphaser_1_timer->enabled()) - lphaser1_sensor_check(machine); - } - else - { - /* disable crosshair */ - crosshair_set_screen(machine, 0, CROSSHAIR_SCREEN_NONE); - state->m_lphaser_1_timer->enable(0); - } - - if ((input_port_read_safe(machine, "CTRLSEL", 0x00) & 0xf0) == 0x10) - { - /* enable crosshair */ - crosshair_set_screen(machine, 1, CROSSHAIR_SCREEN_ALL); - if (!state->m_lphaser_2_timer->enabled()) - lphaser2_sensor_check(machine); - } - else - { - /* disable crosshair */ - crosshair_set_screen(machine, 1, CROSSHAIR_SCREEN_NONE); - state->m_lphaser_2_timer->enable(0); - } -} - - -static TIMER_CALLBACK( lphaser_1_callback ) -{ - lphaser1_sensor_check(machine); -} - - -static TIMER_CALLBACK( lphaser_2_callback ) -{ - lphaser2_sensor_check(machine); -} - - -INPUT_CHANGED( lgun1_changed ) -{ - sms_state *state = field.machine().driver_data(); - if (!state->m_lphaser_1_timer || - (input_port_read_safe(field.machine(), "CTRLSEL", 0x00) & 0x0f) != 0x01) - return; - - if (newval != oldval) - lphaser1_sensor_check(field.machine()); -} - -INPUT_CHANGED( lgun2_changed ) -{ - sms_state *state = field.machine().driver_data(); - if (!state->m_lphaser_2_timer || - (input_port_read_safe(field.machine(), "CTRLSEL", 0x00) & 0xf0) != 0x10) - return; - - if (newval != oldval) - lphaser2_sensor_check(field.machine()); -} - - -static void sms_get_inputs( address_space *space ) -{ - sms_state *state = space->machine().driver_data(); - UINT8 data = 0x00; - UINT32 cpu_cycles = downcast(&space->device())->total_cycles(); - running_machine &machine = space->machine(); - - state->m_input_port0 = 0xff; - state->m_input_port1 = 0xff; - - if (cpu_cycles - state->m_last_paddle_read_time > 256) - { - state->m_paddle_read_state ^= 0xff; - state->m_last_paddle_read_time = cpu_cycles; - } - - /* Check if lightgun has been chosen as input: if so, enable crosshair */ - machine.scheduler().timer_set(attotime::zero, FUNC(lightgun_tick)); - - /* Player 1 */ - switch (input_port_read_safe(machine, "CTRLSEL", 0x00) & 0x0f) - { - case 0x00: /* Joystick */ - data = input_port_read(machine, "PORT_DC"); - /* Check Rapid Fire setting for Button A */ - if (!(data & 0x10) && (input_port_read(machine, "RFU") & 0x01)) - data |= state->m_rapid_fire_state_1 & 0x10; - - /* Check Rapid Fire setting for Button B */ - if (!(data & 0x20) && (input_port_read(machine, "RFU") & 0x02)) - data |= state->m_rapid_fire_state_1 & 0x20; - - state->m_input_port0 = (state->m_input_port0 & 0xc0) | (data & 0x3f); - break; - - case 0x01: /* Light Phaser */ - data = (input_port_read(machine, "CTRLIPT") & 0x01) << 4; - if (!(data & 0x10)) - { - if (input_port_read(machine, "RFU") & 0x01) - data |= state->m_rapid_fire_state_1 & 0x10; - } - /* just consider the button (trigger) bit */ - data |= ~0x10; - state->m_input_port0 = (state->m_input_port0 & 0xc0) | (data & 0x3f); - break; - - case 0x02: /* Paddle Control */ - /* Get button A state */ - data = input_port_read(machine, "PADDLE0"); - - if (state->m_paddle_read_state) - data = data >> 4; - - state->m_input_port0 = (state->m_input_port0 & 0xc0) | (data & 0x0f) | (state->m_paddle_read_state & 0x20) - | ((input_port_read(machine, "CTRLIPT") & 0x02) << 3); - break; - - case 0x03: /* Sega Sports Pad */ - switch (state->m_sports_pad_state_1) - { - case 0: - data = (state->m_sports_pad_1_x >> 4) & 0x0f; - break; - case 1: - data = state->m_sports_pad_1_x & 0x0f; - break; - case 2: - data = (state->m_sports_pad_1_y >> 4) & 0x0f; - break; - case 3: - data = state->m_sports_pad_1_y & 0x0f; - break; - } - state->m_input_port0 = (state->m_input_port0 & 0xc0) | data | ((input_port_read(machine, "CTRLIPT") & 0x0c) << 2); - break; - } - - /* Player 2 */ - switch (input_port_read_safe(machine, "CTRLSEL", 0x00) & 0xf0) - { - case 0x00: /* Joystick */ - data = input_port_read(machine, "PORT_DC"); - state->m_input_port0 = (state->m_input_port0 & 0x3f) | (data & 0xc0); - - data = input_port_read(machine, "PORT_DD"); - /* Check Rapid Fire setting for Button A */ - if (!(data & 0x04) && (input_port_read(machine, "RFU") & 0x04)) - data |= state->m_rapid_fire_state_2 & 0x04; - - /* Check Rapid Fire setting for Button B */ - if (!(data & 0x08) && (input_port_read(machine, "RFU") & 0x08)) - data |= state->m_rapid_fire_state_2 & 0x08; - - state->m_input_port1 = (state->m_input_port1 & 0xf0) | (data & 0x0f); - break; - - case 0x10: /* Light Phaser */ - data = (input_port_read(machine, "CTRLIPT") & 0x10) >> 2; - if (!(data & 0x04)) - { - if (input_port_read(machine, "RFU") & 0x04) - data |= state->m_rapid_fire_state_2 & 0x04; - } - /* just consider the button (trigger) bit */ - data |= ~0x04; - state->m_input_port1 = (state->m_input_port1 & 0xf0) | (data & 0x0f); - break; - - case 0x20: /* Paddle Control */ - /* Get button A state */ - data = input_port_read(machine, "PADDLE1"); - if (state->m_paddle_read_state) - data = data >> 4; - - state->m_input_port0 = (state->m_input_port0 & 0x3f) | ((data & 0x03) << 6); - state->m_input_port1 = (state->m_input_port1 & 0xf0) | ((data & 0x0c) >> 2) | (state->m_paddle_read_state & 0x08) - | ((input_port_read(machine, "CTRLIPT") & 0x20) >> 3); - break; - - case 0x30: /* Sega Sports Pad */ - switch (state->m_sports_pad_state_2) - { - case 0: - data = state->m_sports_pad_2_x & 0x0f; - break; - case 1: - data = (state->m_sports_pad_2_x >> 4) & 0x0f; - break; - case 2: - data = state->m_sports_pad_2_y & 0x0f; - break; - case 3: - data = (state->m_sports_pad_2_y >> 4) & 0x0f; - break; - } - state->m_input_port0 = (state->m_input_port0 & 0x3f) | ((data & 0x03) << 6); - state->m_input_port1 = (state->m_input_port1 & 0xf0) | (data >> 2) | ((input_port_read(machine, "CTRLIPT") & 0xc0) >> 4); - break; - } -} - - -WRITE8_HANDLER( sms_fm_detect_w ) -{ - sms_state *state = space->machine().driver_data(); - - if (state->m_has_fm) - state->m_fm_detect = (data & 0x01); -} - - -READ8_HANDLER( sms_fm_detect_r ) -{ - sms_state *state = space->machine().driver_data(); - - if (state->m_has_fm) - { - return state->m_fm_detect; - } - else - { - if (state->m_bios_port & IO_CHIP) - { - return 0xff; - } - else - { - sms_get_inputs(space); - return state->m_input_port0; - } - } -} - -WRITE8_HANDLER( sms_io_control_w ) -{ - sms_state *state = space->machine().driver_data(); - - if (data & 0x08) - { - /* check if TH pin level is high (1) and was low last time */ - if (data & 0x80 && !(state->m_ctrl_reg & 0x80)) - { - sms_vdp_hcount_latch(space->machine()); - } - sms_input_write(space, 0, (data & 0x20) >> 5); - } - - if (data & 0x02) - { - if (data & 0x20 && !(state->m_ctrl_reg & 0x20)) - { - sms_vdp_hcount_latch(space->machine()); - } - sms_input_write(space, 1, (data & 0x80) >> 7); - } - - state->m_ctrl_reg = data; -} - - -READ8_HANDLER( sms_count_r ) -{ - sms_state *state = space->machine().driver_data(); - - if (offset & 0x01) - return sms_vdp_hcount_latch_r(state->m_vdp, offset); - else - return sms_vdp_vcount_r(state->m_vdp, offset); -} - - -/* - Check if the pause button is pressed. - If the gamegear is in sms mode, check if the start button is pressed. - */ -void sms_pause_callback( running_machine &machine ) -{ - sms_state *state = machine.driver_data(); - - if (state->m_is_gamegear && !(state->m_cartridge[state->m_current_cartridge].features & CF_GG_SMS_MODE)) - return; - - if (!(input_port_read(machine, state->m_is_gamegear ? "START" : "PAUSE") & 0x80)) - { - if (!state->m_paused) - { - cputag_set_input_line(machine, "maincpu", INPUT_LINE_NMI, PULSE_LINE); - } - state->m_paused = 1; - } - else - { - state->m_paused = 0; - } - - /* clear Light Phaser latch flags for next frame */ - state->m_lphaser_1_latch = 0; - state->m_lphaser_2_latch = 0; -} - -READ8_HANDLER( sms_input_port_0_r ) -{ - sms_state *state = space->machine().driver_data(); - - if (state->m_bios_port & IO_CHIP) - { - return 0xff; - } - else - { - sms_get_inputs(space); - return state->m_input_port0; - } -} - - -READ8_HANDLER( sms_input_port_1_r ) -{ - sms_state *state = space->machine().driver_data(); - - if (state->m_bios_port & IO_CHIP) - return 0xff; - - sms_get_inputs(space); - - /* Reset Button */ - state->m_input_port1 = (state->m_input_port1 & 0xef) | (input_port_read_safe(space->machine(), "RESET", 0x01) & 0x01) << 4; - - /* Do region detection if TH of ports A and B are set to output (0) */ - if (!(state->m_ctrl_reg & 0x0a)) - { - /* Move bits 7,5 of IO control port into bits 7, 6 */ - state->m_input_port1 = (state->m_input_port1 & 0x3f) | (state->m_ctrl_reg & 0x80) | (state->m_ctrl_reg & 0x20) << 1; - - /* Inverse region detect value for Japanese machines */ - if (state->m_is_region_japan) - state->m_input_port1 ^= 0xc0; - } - else - { - if (state->m_ctrl_reg & 0x02 && state->m_lphaser_1_latch) - { - state->m_input_port1 &= ~0x40; - state->m_lphaser_1_latch = 0; - } - - if (state->m_ctrl_reg & 0x08 && state->m_lphaser_2_latch) - { - state->m_input_port1 &= ~0x80; - state->m_lphaser_2_latch = 0; - } - } - - return state->m_input_port1; -} - - - -WRITE8_HANDLER( sms_ym2413_register_port_0_w ) -{ - sms_state *state = space->machine().driver_data(); - - if (state->m_has_fm) - ym2413_w(state->m_ym, 0, (data & 0x3f)); -} - - -WRITE8_HANDLER( sms_ym2413_data_port_0_w ) -{ - sms_state *state = space->machine().driver_data(); - - if (state->m_has_fm) - { - logerror("data_port_0_w %x %x\n", offset, data); - ym2413_w(state->m_ym, 1, data); - } -} - - -READ8_HANDLER( gg_input_port_2_r ) -{ - sms_state *state = space->machine().driver_data(); - - //logerror("joy 2 read, val: %02x, pc: %04x\n", ((state->m_is_region_japan ? 0x00 : 0x40) | (input_port_read(machine, "START") & 0x80)), activecpu_get_pc()); - return ((state->m_is_region_japan ? 0x00 : 0x40) | (input_port_read(space->machine(), "START") & 0x80)); -} - - -READ8_HANDLER( sms_sscope_r ) -{ - sms_state *state = space->machine().driver_data(); - return state->m_sscope_state; -} - - -WRITE8_HANDLER( sms_sscope_w ) -{ - sms_state *state = space->machine().driver_data(); - state->m_sscope_state = data; -} - - -READ8_HANDLER( sms_mapper_r ) -{ - sms_state *state = space->machine().driver_data(); - return state->m_mapper[offset]; -} - -/* Terebi Oekaki */ -/* The following code comes from sg1000.c. We should eventually merge these TV Draw implementations */ -static WRITE8_HANDLER( sms_tvdraw_axis_w ) -{ - sms_state *state = space->machine().driver_data(); - UINT8 tvboard_on = input_port_read_safe(space->machine(), "TVDRAW", 0x00); - - if (data & 0x01) - { - state->m_tvdraw_data = tvboard_on ? input_port_read(space->machine(), "TVDRAW_X") : 0x80; - - if (state->m_tvdraw_data < 4) state->m_tvdraw_data = 4; - if (state->m_tvdraw_data > 251) state->m_tvdraw_data = 251; - } - else - { - state->m_tvdraw_data = tvboard_on ? input_port_read(space->machine(), "TVDRAW_Y") + 0x20 : 0x80; - } -} - -static READ8_HANDLER( sms_tvdraw_status_r ) -{ - UINT8 tvboard_on = input_port_read_safe(space->machine(), "TVDRAW", 0x00); - return tvboard_on ? input_port_read(space->machine(), "TVDRAW_PEN") : 0x01; -} - -static READ8_HANDLER( sms_tvdraw_data_r ) -{ - sms_state *state = space->machine().driver_data(); - return state->m_tvdraw_data; -} - - -WRITE8_HANDLER( sms_mapper_w ) -{ - sms_state *state = space->machine().driver_data(); - int page; - UINT8 *SOURCE_BIOS; - UINT8 *SOURCE_CART; - UINT8 *SOURCE; - UINT8 rom_page_count = state->m_cartridge[state->m_current_cartridge].size / 0x4000; - - offset &= 3; - - state->m_mapper[offset] = data; - state->m_mapper_ram[offset] = data; - - if (state->m_cartridge[state->m_current_cartridge].ROM) - { - SOURCE_CART = state->m_cartridge[state->m_current_cartridge].ROM + (( rom_page_count > 0) ? data % rom_page_count : 0) * 0x4000; - } - else - { - SOURCE_CART = state->m_banking_none[1]; - } - - if (state->m_BIOS) - { - SOURCE_BIOS = state->m_BIOS + ((state->m_bios_page_count > 0) ? data % state->m_bios_page_count : 0) * 0x4000; - } - else - { - SOURCE_BIOS = state->m_banking_none[1]; - } - - if (state->m_bios_port & IO_BIOS_ROM || (state->m_is_gamegear && state->m_BIOS == NULL)) - { - if (!(state->m_bios_port & IO_CARTRIDGE) || (state->m_is_gamegear && state->m_BIOS == NULL)) - { - page = (rom_page_count > 0) ? data % rom_page_count : 0; - if (!state->m_cartridge[state->m_current_cartridge].ROM) - return; - SOURCE = SOURCE_CART; - } - else - { - /* nothing to page in */ - return; - } - } - else - { - page = (state->m_bios_page_count > 0) ? data % state->m_bios_page_count : 0; - if (!state->m_BIOS) - return; - SOURCE = SOURCE_BIOS; - } - - switch (offset) - { - case 0: /* Control */ - /* Is it ram or rom? */ - if (data & 0x08) /* it's ram */ - { - state->m_cartridge[state->m_current_cartridge].sram_save = 1; /* SRAM should be saved on exit. */ - if (data & 0x04) - { - LOG(("ram 1 paged.\n")); - SOURCE = state->m_cartridge[state->m_current_cartridge].cartSRAM + 0x4000; - } - else - { - LOG(("ram 0 paged.\n")); - SOURCE = state->m_cartridge[state->m_current_cartridge].cartSRAM; - } - memory_set_bankptr(space->machine(), "bank5", SOURCE); - memory_set_bankptr(space->machine(), "bank6", SOURCE + 0x2000); - } - else /* it's rom */ - { - if (state->m_bios_port & IO_BIOS_ROM || ! state->m_has_bios) - { - page = (rom_page_count > 0) ? state->m_mapper[3] % rom_page_count : 0; - SOURCE = state->m_banking_cart[5]; - } - else - { - page = (state->m_bios_page_count > 0) ? state->m_mapper[3] % state->m_bios_page_count : 0; - SOURCE = state->m_banking_bios[5]; - } - LOG(("rom 2 paged in %x.\n", page)); - memory_set_bankptr(space->machine(), "bank5", SOURCE); - memory_set_bankptr(space->machine(), "bank6", SOURCE + 0x2000); - } - break; - - case 1: /* Select 16k ROM bank for 0400-3FFF */ - LOG(("rom 0 paged in %x.\n", page)); - state->m_banking_bios[2] = SOURCE_BIOS + 0x0400; - state->m_banking_cart[2] = SOURCE_CART + 0x0400; - if (state->m_is_gamegear) - SOURCE = SOURCE_CART; - - memory_set_bankptr(space->machine(), "bank2", SOURCE + 0x0400); - break; - - case 2: /* Select 16k ROM bank for 4000-7FFF */ - LOG(("rom 1 paged in %x.\n", page)); - state->m_banking_bios[3] = SOURCE_BIOS; - state->m_banking_cart[3] = SOURCE_CART; - if (state->m_is_gamegear) - SOURCE = SOURCE_CART; - - memory_set_bankptr(space->machine(), "bank3", SOURCE); - memory_set_bankptr(space->machine(), "bank4", SOURCE + 0x2000); - break; - - case 3: /* Select 16k ROM bank for 8000-BFFF */ - state->m_banking_bios[5] = SOURCE_BIOS; - if (state->m_is_gamegear) - SOURCE = SOURCE_CART; - - if ( state->m_cartridge[state->m_current_cartridge].features & CF_CODEMASTERS_MAPPER) - { - if (SOURCE == SOURCE_CART) - { - SOURCE = state->m_banking_cart[5]; - } - } - else - { - state->m_banking_cart[5] = SOURCE_CART; - } - - if (!(state->m_mapper[0] & 0x08)) /* is RAM disabled? */ - { - LOG(("rom 2 paged in %x.\n", page)); - memory_set_bankptr(space->machine(), "bank5", SOURCE); - memory_set_bankptr(space->machine(), "bank6", SOURCE + 0x2000); - } - break; - } -} - -#ifdef MESS -static WRITE8_HANDLER( sms_korean_zemina_banksw_w ) -{ - sms_state *state = space->machine().driver_data(); - - if (state->m_cartridge[state->m_current_cartridge].features & CF_KOREAN_ZEMINA_MAPPER) - { - UINT8 rom_page_count = state->m_cartridge[state->m_current_cartridge].size / 0x2000; - int page = (rom_page_count > 0) ? data % rom_page_count : 0; - - if (!state->m_cartridge[state->m_current_cartridge].ROM) - return; - - switch (offset & 3) - { - case 0: - state->m_banking_cart[5] = state->m_cartridge[state->m_current_cartridge].ROM + page * 0x2000; - memory_set_bankptr(space->machine(), "bank5", state->m_banking_cart[5]); - break; - case 1: - state->m_banking_cart[6] = state->m_cartridge[state->m_current_cartridge].ROM + page * 0x2000; - memory_set_bankptr(space->machine(), "bank6", state->m_banking_cart[6]); - break; - case 2: - state->m_banking_cart[3] = state->m_cartridge[state->m_current_cartridge].ROM + page * 0x2000; - memory_set_bankptr(space->machine(), "bank3", state->m_banking_cart[3]); - break; - case 3: - state->m_banking_cart[4] = state->m_cartridge[state->m_current_cartridge].ROM + page * 0x2000; - memory_set_bankptr(space->machine(), "bank4", state->m_banking_cart[4]); - break; - } - LOG(("Zemina mapper write: offset %x data %x.\n", offset, page)); - } -} - -static WRITE8_HANDLER( sms_codemasters_page0_w ) -{ - sms_state *state = space->machine().driver_data(); - - if (state->m_cartridge[state->m_current_cartridge].ROM && state->m_cartridge[state->m_current_cartridge].features & CF_CODEMASTERS_MAPPER) - { - UINT8 rom_page_count = state->m_cartridge[state->m_current_cartridge].size / 0x4000; - state->m_banking_cart[1] = state->m_cartridge[state->m_current_cartridge].ROM + ((rom_page_count > 0) ? data % rom_page_count : 0) * 0x4000; - state->m_banking_cart[2] = state->m_banking_cart[1] + 0x0400; - memory_set_bankptr(space->machine(), "bank1", state->m_banking_cart[1]); - memory_set_bankptr(space->machine(), "bank2", state->m_banking_cart[2]); - } -} - - -static WRITE8_HANDLER( sms_codemasters_page1_w ) -{ - sms_state *state = space->machine().driver_data(); - - if (state->m_cartridge[state->m_current_cartridge].ROM && state->m_cartridge[state->m_current_cartridge].features & CF_CODEMASTERS_MAPPER) - { - /* Check if we need to switch in some RAM */ - if (data & 0x80) - { - state->m_cartridge[state->m_current_cartridge].ram_page = data & 0x07; - memory_set_bankptr(space->machine(), "bank6", state->m_cartridge[state->m_current_cartridge].cartRAM + state->m_cartridge[state->m_current_cartridge].ram_page * 0x2000); - } - else - { - UINT8 rom_page_count = state->m_cartridge[state->m_current_cartridge].size / 0x4000; - state->m_banking_cart[3] = state->m_cartridge[state->m_current_cartridge].ROM + ((rom_page_count > 0) ? data % rom_page_count : 0) * 0x4000; - memory_set_bankptr(space->machine(), "bank3", state->m_banking_cart[3]); - memory_set_bankptr(space->machine(), "bank4", state->m_banking_cart[3] + 0x2000); - memory_set_bankptr(space->machine(), "bank6", state->m_banking_cart[5] + 0x2000); - } - } -} -#endif - -static READ8_HANDLER( sms_kor_nobank_r ) -{ -// printf("read %x\n", offset); - return space->read_byte(0xdffc + offset); -} - -static WRITE8_HANDLER( sms_kor_nobank_w ) -{ - sms_state *state = space->machine().driver_data(); - UINT8 *SOURCE_BIOS; - UINT8 *SOURCE = NULL; - - space->write_byte(0xdffc + offset, data); - state->m_mapper[offset] = data; - - // FIXME: the code below (which only handles the BIOS bankswitch at start) should be cleaned up - // currently, it's just a stripped down version of sms_mapper_w - if (state->m_BIOS) - SOURCE_BIOS = state->m_BIOS + ((state->m_bios_page_count > 0) ? data % state->m_bios_page_count : 0) * 0x4000; - else - SOURCE_BIOS = state->m_banking_none[1]; - - if (state->m_bios_port & IO_BIOS_ROM || (state->m_is_gamegear && state->m_BIOS == NULL)) - return; - else - { - if (!state->m_BIOS) - return; - SOURCE = SOURCE_BIOS; - } - -// printf("write %x, %x\n", offset, data); - - switch (offset) - { - case 0: /* Control */ - if (!(data & 0x08)) /* it's not ram */ - { - if (!(state->m_bios_port & IO_BIOS_ROM) && state->m_has_bios) - { - SOURCE = state->m_banking_bios[5]; - memory_set_bankptr(space->machine(), "bank5", SOURCE); - memory_set_bankptr(space->machine(), "bank6", SOURCE + 0x2000); - } - } - break; - - case 1: /* Select 16k ROM bank for 0400-3FFF */ - state->m_banking_bios[2] = SOURCE_BIOS + 0x0400; - memory_set_bankptr(space->machine(), "bank2", SOURCE + 0x0400); - break; - - case 2: /* Select 16k ROM bank for 4000-7FFF */ - state->m_banking_bios[3] = SOURCE_BIOS; - memory_set_bankptr(space->machine(), "bank3", SOURCE); - memory_set_bankptr(space->machine(), "bank4", SOURCE + 0x2000); - break; - - case 3: /* Select 16k ROM bank for 8000-BFFF */ - state->m_banking_bios[5] = SOURCE_BIOS; - if (!(state->m_mapper[0] & 0x08)) /* is RAM disabled? */ - { - memory_set_bankptr(space->machine(), "bank5", SOURCE); - memory_set_bankptr(space->machine(), "bank6", SOURCE + 0x2000); - } - break; - } -} - -WRITE8_HANDLER( sms_bios_w ) -{ - sms_state *state = space->machine().driver_data(); - state->m_bios_port = data; - - logerror("bios write %02x, pc: %04x\n", data, cpu_get_pc(&space->device())); - - setup_rom(space); -} - - -WRITE8_HANDLER( sms_cartram2_w ) -{ - sms_state *state = space->machine().driver_data(); - - if (state->m_mapper[0] & 0x08) - { - logerror("write %02X to cartram at offset #%04X\n", data, offset + 0x2000); - if (state->m_mapper[0] & 0x04) - { - state->m_cartridge[state->m_current_cartridge].cartSRAM[offset + 0x6000] = data; - } - else - { - state->m_cartridge[state->m_current_cartridge].cartSRAM[offset + 0x2000] = data; - } - } - - if (state->m_cartridge[state->m_current_cartridge].features & CF_CODEMASTERS_MAPPER) - { - state->m_cartridge[state->m_current_cartridge].cartRAM[state->m_cartridge[state->m_current_cartridge].ram_page * 0x2000 + offset] = data; - } - - if (state->m_cartridge[state->m_current_cartridge].features & CF_KOREAN_MAPPER && offset == 0) /* Dodgeball King mapper */ - { - UINT8 rom_page_count = state->m_cartridge[state->m_current_cartridge].size / 0x4000; - int page = (rom_page_count > 0) ? data % rom_page_count : 0; - - if (!state->m_cartridge[state->m_current_cartridge].ROM) - return; - - state->m_banking_cart[5] = state->m_cartridge[state->m_current_cartridge].ROM + page * 0x4000; - memory_set_bankptr(space->machine(), "bank5", state->m_banking_cart[5]); - memory_set_bankptr(space->machine(), "bank6", state->m_banking_cart[5] + 0x2000); - LOG(("rom 2 paged in %x (Korean mapper).\n", page)); - } -} - - -WRITE8_HANDLER( sms_cartram_w ) -{ - sms_state *state = space->machine().driver_data(); - int page; - - if (state->m_mapper[0] & 0x08) - { - logerror("write %02X to cartram at offset #%04X\n", data, offset); - if (state->m_mapper[0] & 0x04) - { - state->m_cartridge[state->m_current_cartridge].cartSRAM[offset + 0x4000] = data; - } - else - { - state->m_cartridge[state->m_current_cartridge].cartSRAM[offset] = data; - } - } - else - { - if (state->m_cartridge[state->m_current_cartridge].features & CF_CODEMASTERS_MAPPER && offset == 0) /* Codemasters mapper */ - { - UINT8 rom_page_count = state->m_cartridge[state->m_current_cartridge].size / 0x4000; - page = (rom_page_count > 0) ? data % rom_page_count : 0; - if (!state->m_cartridge[state->m_current_cartridge].ROM) - return; - state->m_banking_cart[5] = state->m_cartridge[state->m_current_cartridge].ROM + page * 0x4000; - memory_set_bankptr(space->machine(), "bank5", state->m_banking_cart[5]); - memory_set_bankptr(space->machine(), "bank6", state->m_banking_cart[5] + 0x2000); - LOG(("rom 2 paged in %x (Codemasters mapper).\n", page)); - } - else if (state->m_cartridge[state->m_current_cartridge].features & CF_ONCART_RAM) - { - state->m_cartridge[state->m_current_cartridge].cartRAM[offset & (state->m_cartridge[state->m_current_cartridge].ram_size - 1)] = data; - } - else - { - logerror("INVALID write %02X to cartram at offset #%04X\n", data, offset); - } - } -} - - -WRITE8_HANDLER( gg_sio_w ) -{ - sms_state *state = space->machine().driver_data(); - logerror("*** write %02X to SIO register #%d\n", data, offset); - - state->m_gg_sio[offset & 0x07] = data; - switch (offset & 7) - { - case 0x00: /* Parallel Data */ - break; - - case 0x01: /* Data Direction/ NMI Enable */ - break; - - case 0x02: /* Serial Output */ - break; - - case 0x03: /* Serial Input */ - break; - - case 0x04: /* Serial Control / Status */ - break; - } -} - - -READ8_HANDLER( gg_sio_r ) -{ - sms_state *state = space->machine().driver_data(); - logerror("*** read SIO register #%d\n", offset); - - switch (offset & 7) - { - case 0x00: /* Parallel Data */ - break; - - case 0x01: /* Data Direction/ NMI Enable */ - break; - - case 0x02: /* Serial Output */ - break; - - case 0x03: /* Serial Input */ - break; - - case 0x04: /* Serial Control / Status */ - break; - } - - return state->m_gg_sio[offset]; -} - -static void sms_machine_stop( running_machine &machine ) -{ - sms_state *state = machine.driver_data(); - - /* Does the cartridge have SRAM that should be saved? */ - if (state->m_cartridge[state->m_current_cartridge].sram_save) { - device_image_interface *image = dynamic_cast(machine.device("cart1")); - image->battery_save(state->m_cartridge[state->m_current_cartridge].cartSRAM, sizeof(UINT8) * NVRAM_SIZE ); - } -} - - -static void setup_rom( address_space *space ) -{ - sms_state *state = space->machine().driver_data(); - running_machine &machine = space->machine(); - - /* 1. set up bank pointers to point to nothing */ - memory_set_bankptr(machine, "bank1", state->m_banking_none[1]); - memory_set_bankptr(machine, "bank2", state->m_banking_none[2]); - memory_set_bankptr(machine, "bank3", state->m_banking_none[3]); - memory_set_bankptr(machine, "bank4", state->m_banking_none[3] + 0x2000); - memory_set_bankptr(machine, "bank5", state->m_banking_none[5]); - memory_set_bankptr(machine, "bank6", state->m_banking_none[5] + 0x2000); - - /* 2. check and set up expansion port */ - if (!(state->m_bios_port & IO_EXPANSION) && (state->m_bios_port & IO_CARTRIDGE) && (state->m_bios_port & IO_CARD)) - { - /* TODO: Implement me */ - logerror("Switching to unsupported expansion port.\n"); - } - - /* 3. check and set up card rom */ - if (!(state->m_bios_port & IO_CARD) && (state->m_bios_port & IO_CARTRIDGE) && (state->m_bios_port & IO_EXPANSION)) - { - /* TODO: Implement me */ - logerror("Switching to unsupported card rom port.\n"); - } - - /* 4. check and set up cartridge rom */ - /* if ((!(bios_port & IO_CARTRIDGE) && (bios_port & IO_EXPANSION) && (bios_port & IO_CARD)) || state->m_is_gamegear) { */ - /* Out Run Europa initially writes a value to port 3E where IO_CARTRIDGE, IO_EXPANSION and IO_CARD are reset */ - if ((!(state->m_bios_port & IO_CARTRIDGE)) || state->m_is_gamegear) - { - memory_set_bankptr(machine, "bank1", state->m_banking_cart[1]); - memory_set_bankptr(machine, "bank2", state->m_banking_cart[2]); - memory_set_bankptr(machine, "bank3", state->m_banking_cart[3]); - memory_set_bankptr(machine, "bank4", state->m_banking_cart[3] + 0x2000); - memory_set_bankptr(machine, "bank5", state->m_banking_cart[5]); - memory_set_bankptr(machine, "bank6", state->m_banking_cart[5] + 0x2000); - logerror("Switched in cartridge rom.\n"); - } - - /* 5. check and set up bios rom */ - if (!(state->m_bios_port & IO_BIOS_ROM)) - { - /* 0x0400 bioses */ - if (state->m_has_bios_0400) - { - memory_set_bankptr(machine, "bank1", state->m_banking_bios[1]); - logerror("Switched in 0x0400 bios.\n"); - } - /* 0x2000 bioses */ - if (state->m_has_bios_2000) - { - memory_set_bankptr(machine, "bank1", state->m_banking_bios[1]); - memory_set_bankptr(machine, "bank2", state->m_banking_bios[2]); - logerror("Switched in 0x2000 bios.\n"); - } - if (state->m_has_bios_full) - { - memory_set_bankptr(machine, "bank1", state->m_banking_bios[1]); - memory_set_bankptr(machine, "bank2", state->m_banking_bios[2]); - memory_set_bankptr(machine, "bank3", state->m_banking_bios[3]); - memory_set_bankptr(machine, "bank4", state->m_banking_bios[3] + 0x2000); - memory_set_bankptr(machine, "bank5", state->m_banking_bios[5]); - memory_set_bankptr(machine, "bank6", state->m_banking_bios[5] + 0x2000); - logerror("Switched in full bios.\n"); - } - } - - if (state->m_cartridge[state->m_current_cartridge].features & CF_ONCART_RAM) - { - memory_set_bankptr(machine, "bank5", state->m_cartridge[state->m_current_cartridge].cartRAM); - memory_set_bankptr(machine, "bank6", state->m_cartridge[state->m_current_cartridge].cartRAM); - } -} - - -static int sms_verify_cart( UINT8 *magic, int size ) -{ - int retval; - - retval = IMAGE_VERIFY_FAIL; - - /* Verify the file is a valid image - check $7ff0 for "TMR SEGA" */ - if (size >= 0x8000) - { - if (!strncmp((char*)&magic[0x7ff0], "TMR SEGA", 8)) - { -#if 0 - /* Technically, it should be this, but remove for now until verified: */ - if (!strcmp(sysname, "gamegear")) - { - if ((unsigned char)magic[0x7ffd] < 0x50) - retval = IMAGE_VERIFY_PASS; - } - if (!strcmp(sysname, "sms")) - { - if ((unsigned char)magic[0x7ffd] >= 0x50) - retval = IMAGE_VERIFY_PASS; - } -#endif - retval = IMAGE_VERIFY_PASS; - } - -#if 0 - /* Check at $81f0 also */ - if (!retval) - { - if (!strncmp(&magic[0x81f0], "TMR SEGA", 8)) - { -#if 0 - /* Technically, it should be this, but remove for now until verified: */ - if (!strcmp(sysname, "gamegear")) - { - if ((unsigned char)magic[0x81fd] < 0x50) - retval = IMAGE_VERIFY_PASS; - } - if (!strcmp(sysname, "sms")) - { - if ((unsigned char)magic[0x81fd] >= 0x50) - retval = IMAGE_VERIFY_PASS; - } -#endif - retval = IMAGE_VERIFY_PASS; - } - } -#endif - - } - - return retval; -} - -#ifdef UNUSED_FUNCTION -// For the moment we switch to a different detection routine which allows to detect -// in a single run Codemasters mapper, Korean mapper (including Jang Pung 3 which -// uses a diff signature then the one below here) and Zemina mapper (used by Wonsiin, etc.). -// I leave these here to document alt. detection routines and in the case these functions -// can be updated - -/* Check for Codemasters mapper - 0x7FE3 - 93 - sms Cosmis Spacehead - - sms Dinobasher - - sms The Excellent Dizzy Collection - - sms Fantastic Dizzy - - sms Micro Machines - - gamegear Cosmic Spacehead - - gamegear Micro Machines - - 94 - gamegear Dropzone - - gamegear Ernie Els Golf (also has 64KB additional RAM on the cartridge) - - gamegear Pete Sampras Tennis - - gamegear S.S. Lucifer - - 95 - gamegear Micro Machines 2 - Turbo Tournament - -The Korean game Jang Pung II also seems to use a codemasters style mapper. - */ -static int detect_codemasters_mapper( UINT8 *rom ) -{ - static const UINT8 jang_pung2[16] = { 0x00, 0xba, 0x38, 0x0d, 0x00, 0xb8, 0x38, 0x0c, 0x00, 0xb6, 0x38, 0x0b, 0x00, 0xb4, 0x38, 0x0a }; - - if (((rom[0x7fe0] & 0x0f ) <= 9) && (rom[0x7fe3] == 0x93 || rom[0x7fe3] == 0x94 || rom[0x7fe3] == 0x95) && rom[0x7fef] == 0x00) - return 1; - - if (!memcmp(&rom[0x7ff0], jang_pung2, 16)) - return 1; - - return 0; -} - - -static int detect_korean_mapper( UINT8 *rom ) -{ - static const UINT8 signatures[2][16] = - { - { 0x3e, 0x11, 0x32, 0x00, 0xa0, 0x78, 0xcd, 0x84, 0x85, 0x3e, 0x02, 0x32, 0x00, 0xa0, 0xc9, 0xff }, /* Dodgeball King */ - { 0x41, 0x48, 0x37, 0x37, 0x44, 0x37, 0x4e, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20 }, /* Sangokushi 3 */ - }; - int i; - - for (i = 0; i < 2; i++) - { - if (!memcmp(&rom[0x7ff0], signatures[i], 16)) - { - return 1; - } - } - return 0; -} -#endif - - -static int detect_tvdraw( UINT8 *rom ) -{ - static const UINT8 terebi_oekaki[7] = { 0x61, 0x6e, 0x6e, 0x61, 0x6b, 0x6d, 0x6e }; // "annakmn" - - if (!memcmp(&rom[0x13b3], terebi_oekaki, 7)) - return 1; - - return 0; -} - - -static int detect_lphaser_xoffset( running_machine &machine, UINT8 *rom ) -{ - sms_state *state = machine.driver_data(); - - static const UINT8 signatures[6][16] = - { - /* Spacegun */ - { 0x54, 0x4d, 0x52, 0x20, 0x53, 0x45, 0x47, 0x41, 0xff, 0xff, 0x9d, 0x99, 0x10, 0x90, 0x00, 0x40 }, - /* Gangster Town */ - { 0x54, 0x4d, 0x52, 0x20, 0x53, 0x45, 0x47, 0x41, 0x19, 0x87, 0x1b, 0xc9, 0x74, 0x50, 0x00, 0x4f }, - /* Shooting Gallery */ - { 0x54, 0x4d, 0x52, 0x20, 0x53, 0x45, 0x47, 0x41, 0x20, 0x20, 0x8a, 0x3a, 0x72, 0x50, 0x00, 0x4f }, - /* Rescue Mission */ - { 0x54, 0x4d, 0x52, 0x20, 0x53, 0x45, 0x47, 0x41, 0x20, 0x20, 0xfb, 0xd3, 0x06, 0x51, 0x00, 0x4f }, - /* Laser Ghost */ - { 0x54, 0x4d, 0x52, 0x20, 0x53, 0x45, 0x47, 0x41, 0x00, 0x00, 0xb7, 0x55, 0x74, 0x70, 0x00, 0x40 }, - /* Assault City */ - { 0x54, 0x4d, 0x52, 0x20, 0x53, 0x45, 0x47, 0x41, 0xff, 0xff, 0x9f, 0x74, 0x34, 0x70, 0x00, 0x40 }, - }; - - if (!(state->m_bios_port & IO_CARTRIDGE) && state->m_cartridge[state->m_current_cartridge].size >= 0x8000) - { - if (!memcmp(&rom[0x7ff0], signatures[0], 16) || !memcmp(&rom[0x7ff0], signatures[1], 16)) - return 40; - - if (!memcmp(&rom[0x7ff0], signatures[2], 16)) - return 49; - - if (!memcmp(&rom[0x7ff0], signatures[3], 16)) - return 47; - - if (!memcmp(&rom[0x7ff0], signatures[4], 16)) - return 44; - - if (!memcmp(&rom[0x7ff0], signatures[5], 16)) - return 53; - - } - return 50; -} - - -DEVICE_START( sms_cart ) -{ - sms_state *state = device->machine().driver_data(); - int i; - - for (i = 0; i < MAX_CARTRIDGES; i++) - { - state->m_cartridge[i].ROM = NULL; - state->m_cartridge[i].size = 0; - state->m_cartridge[i].features = 0; - state->m_cartridge[i].cartSRAM = NULL; - state->m_cartridge[i].sram_save = 0; - state->m_cartridge[i].cartRAM = NULL; - state->m_cartridge[i].ram_size = 0; - state->m_cartridge[i].ram_page = 0; - } - state->m_current_cartridge = 0; - - state->m_bios_port = (IO_EXPANSION | IO_CARTRIDGE | IO_CARD); - if (!state->m_is_gamegear && !state->m_has_bios) - { - state->m_bios_port &= ~(IO_CARTRIDGE); - state->m_bios_port |= IO_BIOS_ROM; - } -} - - -DEVICE_IMAGE_LOAD( sms_cart ) -{ - running_machine &machine = image.device().machine(); - sms_state *state = machine.driver_data(); - int size, index = 0, offset = 0; - const char *extrainfo = NULL; - - if (strcmp(image.device().tag(), "cart1") == 0) - index = 0; - if (strcmp(image.device().tag(), "cart2") == 0) - index = 1; - if (strcmp(image.device().tag(), "cart3") == 0) - index = 2; - if (strcmp(image.device().tag(), "cart4") == 0) - index = 3; - if (strcmp(image.device().tag(), "cart5") == 0) - index = 4; - if (strcmp(image.device().tag(), "cart6") == 0) - index = 5; - if (strcmp(image.device().tag(), "cart7") == 0) - index = 6; - if (strcmp(image.device().tag(), "cart8") == 0) - index = 7; - if (strcmp(image.device().tag(), "cart9") == 0) - index = 8; - if (strcmp(image.device().tag(), "cart10") == 0) - index = 9; - if (strcmp(image.device().tag(), "cart11") == 0) - index = 10; - if (strcmp(image.device().tag(), "cart12") == 0) - index = 11; - if (strcmp(image.device().tag(), "cart13") == 0) - index = 12; - if (strcmp(image.device().tag(), "cart14") == 0) - index = 13; - if (strcmp(image.device().tag(), "cart15") == 0) - index = 14; - if (strcmp(image.device().tag(), "cart16") == 0) - index = 15; - - state->m_cartridge[index].features = 0; - - if (image.software_entry() == NULL) - { - size = image.length(); - extrainfo = hashfile_extrainfo(image); - } - else - size = image.get_software_region_length("rom"); - - /* Check for 512-byte header */ - if ((size / 512) & 1) - { - offset = 512; - size -= 512; - } - - if (!size) - { - image.seterror(IMAGE_ERROR_UNSPECIFIED, "Invalid ROM image: ROM image is too small"); - return IMAGE_INIT_FAIL; - } - - /* Create a new memory region to hold the ROM. */ - /* Make sure the region holds only complete (0x4000) rom banks */ - state->m_cartridge[index].size = (size & 0x3fff) ? (((size >> 14) + 1) << 14) : size; - state->m_cartridge[index].ROM = auto_alloc_array(machine, UINT8, state->m_cartridge[index].size); - state->m_cartridge[index].cartSRAM = auto_alloc_array(machine, UINT8, NVRAM_SIZE); - - /* Load ROM banks */ - if (image.software_entry() == NULL) - { - image.fseek(offset, SEEK_SET); - - if (image.fread( state->m_cartridge[index].ROM, size) != size) - return IMAGE_INIT_FAIL; - } - else - { - memcpy(state->m_cartridge[index].ROM, image.get_software_region("rom") + offset, size); - - // check for mapper feature (currently only KOREAN_NOBANK, but eventually we will add the other mappers as well) - if (image.get_feature("pcb") != NULL) - { - const char *mapper = image.get_feature("pcb"); - if (!strcmp(mapper, "korean_nobank")) - state->m_cartridge[index].features |= CF_KOREAN_NOBANK_MAPPER; - } - } - - /* check the image */ - if (!state->m_has_bios) - { - if (sms_verify_cart(state->m_cartridge[index].ROM, size) == IMAGE_VERIFY_FAIL) - { - logerror("Warning loading image: sms_verify_cart failed\n"); - } - } - - /* Detect special features from the extrainfo field */ - if (extrainfo) - { - /* Check for codemasters mapper */ - if (strstr(extrainfo, "CODEMASTERS")) - state->m_cartridge[index].features |= CF_CODEMASTERS_MAPPER; - - /* Check for korean mapper */ - if (strstr(extrainfo, "KOREAN")) - state->m_cartridge[index].features |= CF_KOREAN_MAPPER; - - /* Check for special SMS Compatibility mode gamegear cartridges */ - if (state->m_is_gamegear && strstr(extrainfo, "GGSMS")) - state->m_cartridge[index].features |= CF_GG_SMS_MODE; - - /* Check for 93C46 eeprom */ - if (strstr(extrainfo, "93C46")) - state->m_cartridge[index].features |= CF_93C46_EEPROM; - - /* Check for 8KB on-cart RAM */ - if (strstr(extrainfo, "8KB_CART_RAM")) - { - state->m_cartridge[index].features |= CF_ONCART_RAM; - state->m_cartridge[index].ram_size = 0x2000; - state->m_cartridge[index].cartRAM = auto_alloc_array(machine, UINT8, state->m_cartridge[index].ram_size); - } - } - else - { - /* If no extrainfo information is available try to find special information out on our own */ - /* Check for special cartridge features (new routine, courtesy of Omar Cornut, from MEKA) */ - if (size >= 0x8000) - { - int c0002 = 0, c8000 = 0, cA000 = 0, cFFFF = 0, i; - for (i = 0; i < 0x8000; i++) - { - if (state->m_cartridge[index].ROM[i] == 0x32) // Z80 opcode for: LD (xxxx), A - { - UINT16 addr = (state->m_cartridge[index].ROM[i + 2] << 8) | state->m_cartridge[index].ROM[i + 1]; - if (addr == 0xFFFF) - { i += 2; cFFFF++; continue; } - if (addr == 0x0002 || addr == 0x0003 || addr == 0x0004) - { i += 2; c0002++; continue; } - if (addr == 0x8000) - { i += 2; c8000++; continue; } - if (addr == 0xA000) - { i += 2; cA000++; continue; } - } - } - - LOG(("Mapper test: c002 = %d, c8000 = %d, cA000 = %d, cFFFF = %d\n", c0002, c8000, cA000, cFFFF)); - - // 2 is a security measure, although tests on existing ROM showed it was not needed - if (c0002 > cFFFF + 2 || (c0002 > 0 && cFFFF == 0)) - state->m_cartridge[index].features |= CF_KOREAN_ZEMINA_MAPPER; - else if (c8000 > cFFFF + 2 || (c8000 > 0 && cFFFF == 0)) - state->m_cartridge[index].features |= CF_CODEMASTERS_MAPPER; - else if (cA000 > cFFFF + 2 || (cA000 > 0 && cFFFF == 0)) - state->m_cartridge[index].features |= CF_KOREAN_MAPPER; - - } - - /* Check for special SMS Compatibility mode gamegear cartridges */ - if (state->m_is_gamegear && image.software_entry() == NULL) // not sure about how to handle this with softlists - { - /* Just in case someone passes us an sms file */ - if (!mame_stricmp (image.filetype(), "sms")) - state->m_cartridge[index].features |= CF_GG_SMS_MODE; - } - } - - if (state->m_cartridge[index].features & CF_CODEMASTERS_MAPPER) - { - state->m_cartridge[index].ram_size = 0x10000; - state->m_cartridge[index].cartRAM = auto_alloc_array(machine, UINT8, state->m_cartridge[index].ram_size); - state->m_cartridge[index].ram_page = 0; - } - - /* For Light Phaser games, we have to detect the x offset */ - state->m_lphaser_x_offs = detect_lphaser_xoffset(machine, state->m_cartridge[index].ROM); - - /* Terebi Oekaki (TV Draw) is a SG1000 game with special input device which is compatible with SG1000 Mark III */ - if ((detect_tvdraw(state->m_cartridge[index].ROM)) && state->m_is_region_japan) - { - address_space *program = machine.device("maincpu")->memory().space(AS_PROGRAM); - program->install_legacy_write_handler(0x6000, 0x6000, FUNC(sms_tvdraw_axis_w)); - program->install_legacy_read_handler(0x8000, 0x8000, FUNC(sms_tvdraw_status_r)); - program->install_legacy_read_handler(0xa000, 0xa000, FUNC(sms_tvdraw_data_r)); - program->nop_write(0xa000, 0xa000); - } - - if (state->m_cartridge[index].features & CF_KOREAN_NOBANK_MAPPER) - { - // FIXME: we should have by default FFFD-FFFF to be only a mirror for DFFD-DFFF (with no bankswitch logic) - // and then the handlers should be installed here for all but the KOREAN_NOBANK carts - // However, to avoid memory map breakage, we currently go the other way around - address_space *program = machine.device("maincpu")->memory().space(AS_PROGRAM); - program->install_legacy_readwrite_handler(0xfffc, 0xffff, FUNC(sms_kor_nobank_r), FUNC(sms_kor_nobank_w)); - } - - LOG(("Cart Features: %x\n", state->m_cartridge[index].features)); - - /* Load battery backed RAM, if available */ - image.battery_load(state->m_cartridge[index].cartSRAM, sizeof(UINT8) * NVRAM_SIZE, 0x00); - - return IMAGE_INIT_PASS; -} - - -static void setup_cart_banks( running_machine &machine ) -{ - sms_state *state = machine.driver_data(); - if (state->m_cartridge[state->m_current_cartridge].ROM) - { - UINT8 rom_page_count = state->m_cartridge[state->m_current_cartridge].size / 0x4000; - state->m_banking_cart[1] = state->m_cartridge[state->m_current_cartridge].ROM; - state->m_banking_cart[2] = state->m_cartridge[state->m_current_cartridge].ROM + 0x0400; - state->m_banking_cart[3] = state->m_cartridge[state->m_current_cartridge].ROM + ((1 < rom_page_count) ? 0x4000 : 0); - state->m_banking_cart[5] = state->m_cartridge[state->m_current_cartridge].ROM + ((2 < rom_page_count) ? 0x8000 : 0); - /* Codemasters mapper points to bank 0 for page 2 */ - if (state->m_cartridge[state->m_current_cartridge].features & CF_CODEMASTERS_MAPPER) - { - state->m_banking_cart[5] = state->m_cartridge[state->m_current_cartridge].ROM; - } - } - else - { - state->m_banking_cart[1] = state->m_banking_none[1]; - state->m_banking_cart[2] = state->m_banking_none[2]; - state->m_banking_cart[3] = state->m_banking_none[3]; - state->m_banking_cart[5] = state->m_banking_none[5]; - } -} - -#ifdef MESS -static void setup_banks( running_machine &machine ) -{ - sms_state *state = machine.driver_data(); - UINT8 *mem = machine.region("maincpu")->base(); - state->m_banking_bios[1] = state->m_banking_cart[1] = state->m_banking_none[1] = mem; - state->m_banking_bios[2] = state->m_banking_cart[2] = state->m_banking_none[2] = mem; - state->m_banking_bios[3] = state->m_banking_cart[3] = state->m_banking_none[3] = mem; - state->m_banking_bios[4] = state->m_banking_cart[4] = state->m_banking_none[4] = mem; - state->m_banking_bios[5] = state->m_banking_cart[5] = state->m_banking_none[5] = mem; - state->m_banking_bios[6] = state->m_banking_cart[6] = state->m_banking_none[6] = mem; - - state->m_BIOS = machine.region("user1")->base(); - - state->m_bios_page_count = (state->m_BIOS ? machine.region("user1")->bytes() / 0x4000 : 0); - - setup_cart_banks(machine); - - if (state->m_BIOS == NULL || state->m_BIOS[0] == 0x00) - { - state->m_BIOS = NULL; - state->m_bios_port |= IO_BIOS_ROM; - } - - if (state->m_BIOS) - { - state->m_banking_bios[1] = state->m_BIOS; - state->m_banking_bios[2] = state->m_BIOS + 0x0400; - state->m_banking_bios[3] = state->m_BIOS + ((1 < state->m_bios_page_count) ? 0x4000 : 0); - state->m_banking_bios[5] = state->m_BIOS + ((2 < state->m_bios_page_count) ? 0x8000 : 0); - } -} -#endif - -MACHINE_START( sms ) -{ - sms_state *state = machine.driver_data(); - - machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(sms_machine_stop),&machine)); - state->m_rapid_fire_timer = machine.scheduler().timer_alloc(FUNC(rapid_fire_callback)); - state->m_rapid_fire_timer->adjust(attotime::from_hz(10), 0, attotime::from_hz(10)); - - state->m_lphaser_1_timer = machine.scheduler().timer_alloc(FUNC(lphaser_1_callback)); - state->m_lphaser_2_timer = machine.scheduler().timer_alloc(FUNC(lphaser_2_callback)); - - state->m_main_cpu = machine.device("maincpu"); - state->m_control_cpu = machine.device("control"); - state->m_vdp = machine.device("sms_vdp"); - state->m_ym = machine.device("ym2413"); - state->m_main_scr = machine.device("screen"); - state->m_left_lcd = machine.device("left_lcd"); - state->m_right_lcd = machine.device("right_lcd"); - - /* Check if lightgun has been chosen as input: if so, enable crosshair */ - machine.scheduler().timer_set(attotime::zero, FUNC(lightgun_tick)); -} - -#ifdef MESS -MACHINE_RESET( sms ) -{ - address_space *space = machine.device("maincpu")->memory().space(AS_PROGRAM); - sms_state *state = machine.driver_data(); - - state->m_ctrl_reg = 0xff; - if (state->m_has_fm) - state->m_fm_detect = 0x01; - - state->m_mapper_ram = (UINT8*)space->get_write_ptr(0xdffc); - - state->m_bios_port = 0; - - if (state->m_cartridge[state->m_current_cartridge].features & CF_CODEMASTERS_MAPPER) - { - /* Install special memory handlers */ - space->install_legacy_write_handler(0x0000, 0x0000, FUNC(sms_codemasters_page0_w)); - space->install_legacy_write_handler(0x4000, 0x4000, FUNC(sms_codemasters_page1_w)); - } - - if (state->m_cartridge[state->m_current_cartridge].features & CF_KOREAN_ZEMINA_MAPPER) - space->install_legacy_write_handler(0x0000, 0x0003, FUNC(sms_korean_zemina_banksw_w)); - - if (state->m_cartridge[state->m_current_cartridge].features & CF_GG_SMS_MODE) - sms_vdp_set_ggsmsmode(state->m_vdp, 1); - - /* Initialize SIO stuff for GG */ - state->m_gg_sio[0] = 0x7f; - state->m_gg_sio[1] = 0xff; - state->m_gg_sio[2] = 0x00; - state->m_gg_sio[3] = 0xff; - state->m_gg_sio[4] = 0x00; - - state->m_store_control = 0; - - setup_banks(machine); - - setup_rom(space); - - state->m_rapid_fire_state_1 = 0; - state->m_rapid_fire_state_2 = 0; - - state->m_last_paddle_read_time = 0; - state->m_paddle_read_state = 0; - - state->m_last_sports_pad_time_1 = 0; - state->m_last_sports_pad_time_2 = 0; - state->m_sports_pad_state_1 = 0; - state->m_sports_pad_state_2 = 0; - state->m_sports_pad_last_data_1 = 0; - state->m_sports_pad_last_data_2 = 0; - state->m_sports_pad_1_x = 0; - state->m_sports_pad_1_y = 0; - state->m_sports_pad_2_x = 0; - state->m_sports_pad_2_y = 0; - - state->m_lphaser_1_latch = 0; - state->m_lphaser_2_latch = 0; - - state->m_sscope_state = 0; - - state->m_tvdraw_data = 0; -} -#endif - -READ8_HANDLER( sms_store_cart_select_r ) -{ - return 0xff; -} - - -WRITE8_HANDLER( sms_store_cart_select_w ) -{ - sms_state *state = space->machine().driver_data(); - UINT8 slot = data >> 4; - UINT8 slottype = data & 0x08; - - logerror("switching in part of %s slot #%d\n", slottype ? "card" : "cartridge", slot ); - /* cartridge? slot #0 */ - if (slottype == 0) - state->m_current_cartridge = slot; - - setup_cart_banks(space->machine()); - memory_set_bankptr(space->machine(), "bank10", state->m_banking_cart[3] + 0x2000); - setup_rom(space); -} - - -READ8_HANDLER( sms_store_select1 ) -{ - return 0xff; -} - - -READ8_HANDLER( sms_store_select2 ) -{ - return 0xff; -} - - -READ8_HANDLER( sms_store_control_r ) -{ - sms_state *state = space->machine().driver_data(); - return state->m_store_control; -} - - -WRITE8_HANDLER( sms_store_control_w ) -{ - sms_state *state = space->machine().driver_data(); - logerror("0x%04X: sms_store_control write 0x%02X\n", cpu_get_pc(&space->device()), data); - if (data & 0x02) - { - space->machine().device("maincpu")->resume(SUSPEND_REASON_HALT); - } - else - { - /* Pull reset line of CPU #0 low */ - space->machine().device("maincpu")->reset(); - space->machine().device("maincpu")->suspend(SUSPEND_REASON_HALT, 1); - } - state->m_store_control = data; -} - -void sms_store_int_callback( running_machine &machine, int state ) -{ - sms_state *driver_state = machine.driver_data(); - device_set_input_line(driver_state->m_store_control & 0x01 ? driver_state->m_control_cpu : driver_state->m_main_cpu, 0, state); -} - - -static void sms_set_zero_flag( running_machine &machine ) -{ - sms_state *state = machine.driver_data(); - state->m_is_gamegear = 0; - state->m_is_region_japan = 0; - state->m_has_bios_0400 = 0; - state->m_has_bios_2000 = 0; - state->m_has_bios_full = 0; - state->m_has_bios = 0; - state->m_has_fm = 0; -} - -DRIVER_INIT( sg1000m3 ) -{ - sms_state *state = machine.driver_data(); - sms_set_zero_flag(machine); - state->m_is_region_japan = 1; - state->m_has_fm = 1; -} - - -DRIVER_INIT( sms1 ) -{ - sms_state *state = machine.driver_data(); - sms_set_zero_flag(machine); - state->m_has_bios_full = 1; -} - - -DRIVER_INIT( smsj ) -{ - sms_state *state = machine.driver_data(); - sms_set_zero_flag(machine); - state->m_is_region_japan = 1; - state->m_has_bios_2000 = 1; - state->m_has_fm = 1; -} - - -DRIVER_INIT( sms2kr ) -{ - sms_state *state = machine.driver_data(); - sms_set_zero_flag(machine); - state->m_is_region_japan = 1; - state->m_has_bios_full = 1; - state->m_has_fm = 1; -} - - -DRIVER_INIT( smssdisp ) -{ - sms_set_zero_flag(machine); -} - - -DRIVER_INIT( gamegear ) -{ - sms_state *state = machine.driver_data(); - sms_set_zero_flag(machine); - state->m_is_gamegear = 1; -} - - -DRIVER_INIT( gamegeaj ) -{ - sms_state *state = machine.driver_data(); - sms_set_zero_flag(machine); - state->m_is_region_japan = 1; - state->m_is_gamegear = 1; - state->m_has_bios_0400 = 1; -} - - -static void sms_black_bitmap( const screen_device *screen, bitmap_t *bitmap ) -{ - const int width = screen->width(); - const int height = screen->height(); - int x, y; - - for (y = 0; y < height; y++) - for (x = 0; x < width; x++) - *BITMAP_ADDR32(bitmap, y, x) = MAKE_RGB(0,0,0); -} - -VIDEO_START( sms1 ) -{ - sms_state *state = machine.driver_data(); - screen_device *screen = machine.first_screen(); - int width = screen->width(); - int height = screen->height(); - - state->m_prevleft_bitmap = auto_bitmap_alloc(machine, width, height, BITMAP_FORMAT_INDEXED32); - state->m_prevright_bitmap = auto_bitmap_alloc(machine, width, height, BITMAP_FORMAT_INDEXED32); - state->save_item(NAME(*state->m_prevleft_bitmap)); - state->save_item(NAME(*state->m_prevright_bitmap)); -} - -SCREEN_UPDATE( sms1 ) -{ - sms_state *state = screen->machine().driver_data(); - UINT8 sscope = input_port_read_safe(screen->machine(), "SEGASCOPE", 0x00); - UINT8 sscope_binocular_hack = input_port_read_safe(screen->machine(), "SSCOPE_BINOCULAR", 0x00); - UINT8 occluded_view = 0; - - // without SegaScope, both LCDs for glasses go black - if ((screen != state->m_main_scr) && !sscope) - occluded_view = 1; - - // with SegaScope, sscope_state 0 = left screen OFF, right screen ON - if (!(state->m_sscope_state & 0x01) && (screen == state->m_left_lcd)) - occluded_view = 1; - - // with SegaScope, sscope_state 1 = left screen ON, right screen OFF - if ((state->m_sscope_state & 0x01) && (screen == state->m_right_lcd)) - occluded_view = 1; - - if (!occluded_view) - { - sms_vdp_update(state->m_vdp, bitmap, cliprect); - - // HACK: fake 3D->2D handling (if enabled, it repeats each frame twice on the selected lens) - // save a copy of current bitmap for the binocular hack - if (sscope && (screen == state->m_left_lcd) && (sscope_binocular_hack & 0x01)) - copybitmap(state->m_prevleft_bitmap, bitmap, 0, 0, 0, 0, cliprect); - if (sscope && (screen == state->m_right_lcd) && (sscope_binocular_hack & 0x02)) - copybitmap(state->m_prevright_bitmap, bitmap, 0, 0, 0, 0, cliprect); - } - else - { - sms_black_bitmap(screen, bitmap); - - // HACK: fake 3D->2D handling (if enabled, it repeats each frame twice on the selected lens) - // use the copied bitmap for the binocular hack - if (sscope && (screen == state->m_left_lcd) && (sscope_binocular_hack & 0x01)) - copybitmap(bitmap, state->m_prevleft_bitmap, 0, 0, 0, 0, cliprect); - if (sscope && (screen == state->m_right_lcd) && (sscope_binocular_hack & 0x02)) - copybitmap(bitmap, state->m_prevright_bitmap, 0, 0, 0, 0, cliprect); - } - - return 0; -} - -SCREEN_UPDATE( sms ) -{ - sms_state *state = screen->machine().driver_data(); - sms_vdp_update(state->m_vdp, bitmap, cliprect); - return 0; -} - -VIDEO_START( gamegear ) -{ - sms_state *state = machine.driver_data(); - screen_device *screen = machine.first_screen(); - int width = screen->width(); - int height = screen->height(); - - state->m_prev_bitmap = auto_bitmap_alloc(machine, width, height, BITMAP_FORMAT_INDEXED32); - state->m_tmp_bitmap = auto_bitmap_alloc(machine, width, height, BITMAP_FORMAT_INDEXED32); - state->save_item(NAME(*state->m_prev_bitmap)); -} - -SCREEN_UPDATE( gamegear ) -{ - sms_state *state = screen->machine().driver_data(); - int width = screen->width(); - int height = screen->height(); - int x, y; - - sms_vdp_update(state->m_vdp, state->m_tmp_bitmap, cliprect); - - // HACK: fake LCD persistence effect - // (it would be better to generalize this in the core, to be used for all LCD systems) - for (y = 0; y < height; y++) - { - UINT32 *line0 = BITMAP_ADDR32(state->m_tmp_bitmap, y, 0); - UINT32 *line1 = BITMAP_ADDR32(state->m_prev_bitmap, y, 0); - for (x = 0; x < width; x++) - { - UINT32 color0 = line0[x]; - UINT32 color1 = line1[x]; - UINT16 r0 = (color0 >> 16) & 0x000000ff; - UINT16 g0 = (color0 >> 8) & 0x000000ff; - UINT16 b0 = (color0 >> 0) & 0x000000ff; - UINT16 r1 = (color1 >> 16) & 0x000000ff; - UINT16 g1 = (color1 >> 8) & 0x000000ff; - UINT16 b1 = (color1 >> 0) & 0x000000ff; - UINT8 r = (UINT8)((r0 + r1) >> 1); - UINT8 g = (UINT8)((g0 + g1) >> 1); - UINT8 b = (UINT8)((b0 + b1) >> 1); - *BITMAP_ADDR32(bitmap, y, x) = (r << 16) | (g << 8) | b; - } - } - copybitmap(state->m_prev_bitmap, state->m_tmp_bitmap, 0, 0, 0, 0, cliprect); - - return 0; -} diff --git a/src/mame/mame.mak b/src/mame/mame.mak index c9975c1f4d0..fd16701cecf 100644 --- a/src/mame/mame.mak +++ b/src/mame/mame.mak @@ -1220,9 +1220,6 @@ $(MAMEOBJ)/sega.a: \ $(VIDEO)/segaic16.o \ $(VIDEO)/sega16sp.o \ $(VIDEO)/segaic24.o \ - $(VIDEO)/smsvdp.o \ - $(MACHINE)/segasms.o \ - $(DRIVERS)/segasms.o \ $(MACHINE)/gdrom.o \ $(MAMEOBJ)/seibu.a: \ diff --git a/src/mame/video/smsvdp.c b/src/mame/video/smsvdp.c deleted file mode 100644 index e3348f86c2c..00000000000 --- a/src/mame/video/smsvdp.c +++ /dev/null @@ -1,1530 +0,0 @@ -/********************************************************************* - - smsvdp.c - - Implementation of video hardware chip used by Sega Master System - -**********************************************************************/ - -/* - For more information, please see: - - http://cgfm2.emuviews.com/txt/msvdp.txt - - http://www.smspower.org/forums/viewtopic.php?p=44198 - -A scanline contains the following sections: - - horizontal sync 1 ED => HSYNC high/increment line counter/generate interrupts/etc - - left blanking 2 ED-EE - - color burst 14 EE-EF - - left blanking 8 F5-F9 - - left border 13 F9-FF - - active display 256 00-7F - - right border 15 80-87 - - right blanking 8 87-8B - - horizontal sync 25 8B-97 => HSYNC low - - -NTSC frame timing - 256x192 256x224 256x240 (doesn't work on real hardware) - - vertical blanking 3 D5-D7 3 E5-E7 3 EE-F0 - - top blanking 13 D8-E4 13 E8-F4 13 F1-FD - - top border 27 E5-FF 11 F5-FF 3 FD-FF - - active display 192 00-BF 224 00-DF 240 00-EF - - bottom border 24 C0-D7 8 E0-E7 0 F0-F0 - - bottom blanking 3 D8-DA 3 E8-EA 3 F0-F2 - - -PAL frame timing - 256x192 256x224 256x240 - - vertical blanking 3 BA-BC 3 CA-CC 3 D2-D4 - - top blanking 13 BD-C9 13 CD-D9 13 D5-E1 - - top border 54 CA-FF 38 DA-FF 30 E2-FF - - active display 192 00-BF 224 00-DF 240 00-EF - - bottom border 48 C0-EF 32 E0-FF 24 F0-07 - - bottom blanking 3 F0-F2 3 00-02 3 08-0A - - TODO: - - implement differences between SMS1_VDP & SMS_VDP/GG_VDP - -*/ - -#include "emu.h" -#include "video/smsvdp.h" - -#define IS_SMS1_VDP (smsvdp->features & MODEL_315_5124) -#define IS_SMS2_VDP (smsvdp->features & MODEL_315_5246) -#define IS_GAMEGEAR_VDP (smsvdp->features & MODEL_315_5378) - -#define STATUS_VINT 0x80 /* Pending vertical interrupt flag */ -#define STATUS_SPROVR 0x40 /* Sprite overflow flag */ -#define STATUS_SPRCOL 0x20 /* Object collision flag */ -#define STATUS_HINT 0x02 /* Pending horizontal interrupt flag */ - -#define VINT_HPOS 23 -#define HINT_HPOS 23 -#define VCOUNT_CHANGE_HPOS 22 -#define VINT_FLAG_HPOS 7 -#define SPROVR_HPOS 6 -#define SPRCOL_BASEHPOS 42 -#define DISPLAY_CB_HPOS 5 /* fix X-Scroll latchtime (Flubba's VDPTest) */ - -#define GG_CRAM_SIZE 0x40 /* 32 colors x 2 bytes per color = 64 bytes */ -#define SMS_CRAM_SIZE 0x20 /* 32 colors x 1 bytes per color = 32 bytes */ -#define MAX_CRAM_SIZE 0x40 - -#define VRAM_SIZE 0x4000 - -#define PRIORITY_BIT 0x1000 -#define BACKDROP_COLOR ((smsvdp->vdp_mode == 4 ? 0x10 : 0x00) + (smsvdp->reg[0x07] & 0x0f)) - -#define NUM_OF_REGISTER 0x10 /* 16 registers */ - -#define INIT_VCOUNT 0 -#define VERTICAL_BLANKING 1 -#define TOP_BLANKING 2 -#define TOP_BORDER 3 -#define ACTIVE_DISPLAY_V 4 -#define BOTTOM_BORDER 5 -#define BOTTOM_BLANKING 6 - -static const UINT8 sms_ntsc_192[7] = { 0xd5, 3, 13, 27, 192, 24, 3 }; -static const UINT8 sms_ntsc_224[7] = { 0xe5, 3, 13, 11, 224, 8, 3 }; -static const UINT8 sms_ntsc_240[7] = { 0xee, 3, 13, 3, 240, 0, 3 }; -static const UINT8 sms_pal_192[7] = { 0xba, 3, 13, 54, 192, 48, 3 }; -static const UINT8 sms_pal_224[7] = { 0xca, 3, 13, 38, 224, 32, 3 }; -static const UINT8 sms_pal_240[7] = { 0xd2, 3, 13, 30, 240, 24, 3 }; - - -typedef struct _smsvdp_t smsvdp_t; -struct _smsvdp_t -{ - UINT32 features; - UINT8 reg[NUM_OF_REGISTER]; /* All the registers */ - UINT8 status; /* Status register */ - UINT8 reg9copy; /* Internal copy of register 9 */ - UINT8 addrmode; /* Type of VDP action */ - UINT16 addr; /* Contents of internal VDP address register */ - UINT8 cram_mask; /* Mask to switch between SMS and GG CRAM sizes */ - int cram_dirty; /* Have there been any changes to the CRAM area */ - int pending; - UINT8 buffer; - int gg_sms_mode; /* Shrunk SMS screen on GG lcd mode flag */ - int irq_state; /* The status of the IRQ line of the VDP */ - int vdp_mode; /* Current mode of the VDP: 0,1,2,3,4 */ - int y_pixels; /* 192, 224, 240 */ - UINT8 line_counter; - UINT8 hcounter; - memory_region *VRAM; /* Pointer to VRAM */ - memory_region *CRAM; /* Pointer to CRAM */ - const UINT8 *sms_frame_timing; - bitmap_t *tmpbitmap; - UINT8 *collision_buffer; - - /* line_buffer will be used to hold 5 lines of line data. Line #0 is the regular blitting area. - Lines #1-#4 will be used as a kind of cache to be used for vertical scaling in the gamegear - sms compatibility mode. */ - int *line_buffer; - int current_palette[32]; - smsvdp_int_cb int_callback; - smsvdp_pause_cb pause_callback; - emu_timer *smsvdp_display_timer; -}; - -static TIMER_CALLBACK( smsvdp_display_callback ); -static void sms_refresh_line( running_machine &machine, smsvdp_t *smsvdp, bitmap_t *bitmap, int offsetx, int offsety, int line ); -static void sms_update_palette( smsvdp_t *smsvdp ); - - -/***************************************************************************** - INLINE FUNCTIONS -*****************************************************************************/ - -INLINE smsvdp_t *get_safe_token(device_t *device) -{ - assert(device != NULL); - assert(device->type() == SMSVDP); - - return (smsvdp_t *)downcast(device)->token(); -} - -INLINE const smsvdp_interface *get_interface(device_t *device) -{ - assert(device != NULL); - assert((device->type() == SMSVDP)); - return (const smsvdp_interface *) device->static_config(); -} - -/************************************* - * - * Utilities - * - *************************************/ - -static void set_display_settings( device_t *device ) -{ - smsvdp_t *smsvdp = get_safe_token(device); - - screen_device *screen = device->machine().first_screen(); - int height = screen->height(); - int M1, M2, M3, M4; - M1 = smsvdp->reg[0x01] & 0x10; - M2 = smsvdp->reg[0x00] & 0x02; - M3 = smsvdp->reg[0x01] & 0x08; - M4 = smsvdp->reg[0x00] & 0x04; - smsvdp->y_pixels = 192; - if (M4) - { - /* mode 4 */ - smsvdp->vdp_mode = 4; - if (M2 && (IS_SMS2_VDP || IS_GAMEGEAR_VDP)) - { - if (M1 && !M3) - smsvdp->y_pixels = 224; /* 224-line display */ - else if (!M1 && M3) - smsvdp->y_pixels = 240; /* 240-line display */ - } - } - else - { - /* original TMS9918 mode */ - if (!M1 && !M2 && !M3) - { - smsvdp->vdp_mode = 0; - } - else -// if (M1 && !M2 && !M3) -// { -// smsvdp->vdp_mode = 1; -// } -// else - if (!M1 && M2 && !M3) - { - smsvdp->vdp_mode = 2; -// } -// else -// if (!M1 && !M2 && M3) -// { -// smsvdp->vdp_mode = 3; - } - else - { - logerror("Unknown video mode detected (M1 = %c, M2 = %c, M3 = %c, M4 = %c)\n", M1 ? '1' : '0', M2 ? '1' : '0', M3 ? '1' : '0', M4 ? '1' : '0'); - } - } - - switch (smsvdp->y_pixels) - { - case 192: - smsvdp->sms_frame_timing = (height == PAL_Y_PIXELS) ? sms_pal_192 : sms_ntsc_192; - break; - - case 224: - smsvdp->sms_frame_timing = (height == PAL_Y_PIXELS) ? sms_pal_224 : sms_ntsc_224; - break; - - case 240: - smsvdp->sms_frame_timing = (height == PAL_Y_PIXELS) ? sms_pal_240 : sms_ntsc_240; - break; - } - smsvdp->cram_dirty = 1; -} - - -READ8_DEVICE_HANDLER( sms_vdp_vcount_r ) -{ - smsvdp_t *smsvdp = get_safe_token(device); - int vpos = device->machine().primary_screen->vpos(); - - if (device->machine().primary_screen->hpos() < VCOUNT_CHANGE_HPOS) - { - vpos--; - if (vpos < 0) - vpos += device->machine().primary_screen->height(); - } - - return (smsvdp->sms_frame_timing[INIT_VCOUNT] + vpos) & 0xff; -} - - -READ8_DEVICE_HANDLER( sms_vdp_hcount_latch_r ) -{ - smsvdp_t *smsvdp = get_safe_token(device); - - return smsvdp->hcounter; -} - -WRITE8_DEVICE_HANDLER( sms_vdp_hcount_latch_w ) -{ - smsvdp_t *smsvdp = get_safe_token(device); - - smsvdp->hcounter = data; -} - - -void sms_vdp_set_ggsmsmode( device_t *device, int mode ) -{ - smsvdp_t *smsvdp = get_safe_token(device); - - smsvdp->gg_sms_mode = mode; - smsvdp->cram_mask = (IS_GAMEGEAR_VDP && !smsvdp->gg_sms_mode) ? (GG_CRAM_SIZE - 1) : (SMS_CRAM_SIZE - 1); -} - - -static TIMER_CALLBACK( smsvdp_set_status ) -{ - smsvdp_t *smsvdp = (smsvdp_t *) ptr; - - smsvdp->status |= (UINT8) param; -} - - -static TIMER_CALLBACK( smsvdp_check_hint ) -{ - smsvdp_t *smsvdp = (smsvdp_t *) ptr; - - if (smsvdp->line_counter == 0x00) - { - smsvdp->line_counter = smsvdp->reg[0x0a]; - smsvdp->status |= STATUS_HINT; - } - else - { - smsvdp->line_counter--; - } - - if ((smsvdp->status & STATUS_HINT) && (smsvdp->reg[0x00] & 0x10)) - { - smsvdp->irq_state = 1; - - if (smsvdp->int_callback) - smsvdp->int_callback(machine, ASSERT_LINE); - } -} - - -static TIMER_CALLBACK( smsvdp_check_vint ) -{ - smsvdp_t *smsvdp = (smsvdp_t *) ptr; - - if ((smsvdp->status & STATUS_VINT) && (smsvdp->reg[0x01] & 0x20)) - { - smsvdp->irq_state = 1; - - if (smsvdp->int_callback) - smsvdp->int_callback(machine, ASSERT_LINE); - } -} - - -static TIMER_CALLBACK( smsvdp_display_callback ) -{ - smsvdp_t *smsvdp = (smsvdp_t *) ptr; - - rectangle rec; - int vpos = machine.primary_screen->vpos(); - int vpos_limit = smsvdp->sms_frame_timing[VERTICAL_BLANKING] + smsvdp->sms_frame_timing[TOP_BLANKING] - + smsvdp->sms_frame_timing[TOP_BORDER] + smsvdp->sms_frame_timing[ACTIVE_DISPLAY_V] - + smsvdp->sms_frame_timing[BOTTOM_BORDER] + smsvdp->sms_frame_timing[BOTTOM_BLANKING]; - - rec.min_y = rec.max_y = vpos; - - /* Check if we're on the last line of a frame */ - if (vpos == vpos_limit - 1) - { - smsvdp->line_counter = smsvdp->reg[0x0a]; - if (smsvdp->pause_callback) - smsvdp->pause_callback(machine); - - return; - } - - vpos_limit -= smsvdp->sms_frame_timing[BOTTOM_BLANKING]; - - /* Check if we're below the bottom border */ - if (vpos >= vpos_limit) - { - smsvdp->line_counter = smsvdp->reg[0x0a]; - return; - } - - vpos_limit -= smsvdp->sms_frame_timing[BOTTOM_BORDER]; - - /* Check if we're in the bottom border area */ - if (vpos >= vpos_limit) - { - if (vpos == vpos_limit) - { - machine.scheduler().timer_set(machine.primary_screen->time_until_pos(vpos, HINT_HPOS), FUNC(smsvdp_check_hint),0 ,smsvdp); - } - else - { - smsvdp->line_counter = smsvdp->reg[0x0a]; - } - - if (vpos == vpos_limit + 1) - { - machine.scheduler().timer_set(machine.primary_screen->time_until_pos(vpos, VINT_FLAG_HPOS), FUNC(smsvdp_set_status), (int)STATUS_VINT, smsvdp); - machine.scheduler().timer_set(machine.primary_screen->time_until_pos(vpos, VINT_HPOS), FUNC(smsvdp_check_vint), 0, smsvdp); - } - - sms_update_palette(smsvdp); - - /* Draw left border */ - rec.min_x = LBORDER_START; - rec.max_x = LBORDER_START + LBORDER_X_PIXELS - 1; - bitmap_fill(smsvdp->tmpbitmap, &rec, machine.pens[smsvdp->current_palette[BACKDROP_COLOR]]); - - /* Draw right border */ - rec.min_x = LBORDER_START + LBORDER_X_PIXELS + 256; - rec.max_x = rec.min_x + RBORDER_X_PIXELS - 1; - bitmap_fill(smsvdp->tmpbitmap, &rec, machine.pens[smsvdp->current_palette[BACKDROP_COLOR]]); - - /* Draw middle of the border */ - /* We need to do this through the regular drawing function so it will */ - /* be included in the gamegear scaling functions */ - sms_refresh_line(machine, smsvdp, smsvdp->tmpbitmap, LBORDER_START + LBORDER_X_PIXELS, vpos_limit - smsvdp->sms_frame_timing[ACTIVE_DISPLAY_V], vpos - (vpos_limit - smsvdp->sms_frame_timing[ACTIVE_DISPLAY_V])); - return; - } - - vpos_limit -= smsvdp->sms_frame_timing[ACTIVE_DISPLAY_V]; - - /* Check if we're in the active display area */ - if (vpos >= vpos_limit) - { - if (vpos == vpos_limit) - { - smsvdp->reg9copy = smsvdp->reg[0x09]; - } - - machine.scheduler().timer_set(machine.primary_screen->time_until_pos(vpos, HINT_HPOS), FUNC(smsvdp_check_hint),0, smsvdp); - - sms_update_palette(smsvdp); - - /* Draw left border */ - rec.min_x = LBORDER_START; - rec.max_x = LBORDER_START + LBORDER_X_PIXELS - 1; - bitmap_fill(smsvdp->tmpbitmap, &rec, machine.pens[smsvdp->current_palette[BACKDROP_COLOR]]); - - /* Draw right border */ - rec.min_x = LBORDER_START + LBORDER_X_PIXELS + 256; - rec.max_x = rec.min_x + RBORDER_X_PIXELS - 1; - bitmap_fill(smsvdp->tmpbitmap, &rec, machine.pens[smsvdp->current_palette[BACKDROP_COLOR]]); - - sms_refresh_line(machine, smsvdp, smsvdp->tmpbitmap, LBORDER_START + LBORDER_X_PIXELS, vpos_limit, vpos - vpos_limit); - - return; - } - - vpos_limit -= smsvdp->sms_frame_timing[TOP_BORDER]; - - /* Check if we're in the top border area */ - if (vpos >= vpos_limit) - { - smsvdp->line_counter = smsvdp->reg[0x0a]; - sms_update_palette(smsvdp); - - /* Draw left border */ - rec.min_x = LBORDER_START; - rec.max_x = LBORDER_START + LBORDER_X_PIXELS - 1; - bitmap_fill(smsvdp->tmpbitmap, &rec, machine.pens[smsvdp->current_palette[BACKDROP_COLOR]]); - - /* Draw right border */ - rec.min_x = LBORDER_START + LBORDER_X_PIXELS + 256; - rec.max_x = rec.min_x + RBORDER_X_PIXELS - 1; - bitmap_fill(smsvdp->tmpbitmap, &rec, machine.pens[smsvdp->current_palette[BACKDROP_COLOR]]); - - /* Draw middle of the border */ - /* We need to do this through the regular drawing function so it will */ - /* be included in the gamegear scaling functions */ - sms_refresh_line(machine, smsvdp, smsvdp->tmpbitmap, LBORDER_START + LBORDER_X_PIXELS, vpos_limit + smsvdp->sms_frame_timing[TOP_BORDER], vpos - (vpos_limit + smsvdp->sms_frame_timing[TOP_BORDER])); - return; - } - - /* we're in the vertical or top blanking area */ - smsvdp->line_counter = smsvdp->reg[0x0a]; -} - - -READ8_DEVICE_HANDLER( sms_vdp_data_r ) -{ - smsvdp_t *smsvdp = get_safe_token(device); - UINT8 temp; - - /* SMS 2 & GG behaviour. Seems like the latched data is passed straight through */ - /* to the address register when in the middle of doing a command. */ - /* Cosmic Spacehead needs this, among others */ - /* Clear pending write flag */ - smsvdp->pending = 0; - - /* Return read buffer contents */ - temp = smsvdp->buffer; - - /* Load read buffer */ - smsvdp->buffer = smsvdp->VRAM->u8((smsvdp->addr & 0x3fff)); - - /* Bump internal address register */ - smsvdp->addr += 1; - return temp; -} - - -READ8_DEVICE_HANDLER( sms_vdp_ctrl_r ) -{ - smsvdp_t *smsvdp = get_safe_token(device); - - UINT8 temp = smsvdp->status; - - /* Clear pending write flag */ - smsvdp->pending = 0; - - smsvdp->status &= ~(STATUS_VINT | STATUS_SPROVR | STATUS_SPRCOL | STATUS_HINT); - - if (smsvdp->irq_state == 1) - { - smsvdp->irq_state = 0; - - if (smsvdp->int_callback) - smsvdp->int_callback(device->machine(), CLEAR_LINE); - } - - /* low 5 bits return non-zero data (it fixes PGA Tour Golf course map introduction) */ - return temp | 0x1f; -} - - -WRITE8_DEVICE_HANDLER( sms_vdp_data_w ) -{ - smsvdp_t *smsvdp = get_safe_token(device); - int address; - - /* SMS 2 & GG behaviour. Seems like the latched data is passed straight through */ - /* to the address register when in the middle of doing a command. */ - /* Cosmic Spacehead needs this, among others */ - /* Clear pending write flag */ - smsvdp->pending = 0; - - switch(smsvdp->addrmode) - { - case 0x00: - case 0x01: - case 0x02: - address = (smsvdp->addr & 0x3fff); - smsvdp->VRAM->u8(address) = data; - break; - - case 0x03: - address = smsvdp->addr & smsvdp->cram_mask; - if (data != smsvdp->CRAM->u8(address)) - { - smsvdp->CRAM->u8(address) = data; - smsvdp->cram_dirty = 1; - } - break; - } - - smsvdp->buffer = data; - smsvdp->addr += 1; -} - - -WRITE8_DEVICE_HANDLER( sms_vdp_ctrl_w ) -{ - smsvdp_t *smsvdp = get_safe_token(device); - - int reg_num; - - if (smsvdp->pending == 0) - { - smsvdp->addr = (smsvdp->addr & 0xff00) | data; - smsvdp->pending = 1; - } - else - { - /* Clear pending write flag */ - smsvdp->pending = 0; - - smsvdp->addrmode = (data >> 6) & 0x03; - smsvdp->addr = (data << 8) | (smsvdp->addr & 0xff); - switch (smsvdp->addrmode) - { - case 0: /* VRAM reading mode */ - smsvdp->buffer = smsvdp->VRAM->u8(smsvdp->addr & 0x3fff); - smsvdp->addr += 1; - break; - - case 1: /* VRAM writing mode */ - break; - - case 2: /* VDP register write */ - reg_num = data & 0x0f; - smsvdp->reg[reg_num] = smsvdp->addr & 0xff; - if (reg_num == 0 && smsvdp->addr & 0x02) - logerror("overscan enabled.\n"); - - if (reg_num == 0 || reg_num == 1) - set_display_settings(device); - - if (reg_num == 1) - { - device->machine().scheduler().timer_set(device->machine().primary_screen->time_until_pos(device->machine().primary_screen->vpos(), VINT_HPOS), FUNC(smsvdp_check_vint),0 ,smsvdp); - } - smsvdp->addrmode = 0; - break; - - case 3: /* CRAM writing mode */ - break; - } - } -} - - -static void sms_refresh_line_mode4( smsvdp_t *smsvdp, int *line_buffer, int *priority_selected, int line ) -{ - int tile_column; - int x_scroll, y_scroll, x_scroll_start_column; - int pixel_x, pixel_plot_x; - int bit_plane_0, bit_plane_1, bit_plane_2, bit_plane_3; - int scroll_mod; - UINT16 name_table_address; - UINT8 *name_table; - - if (smsvdp->y_pixels != 192) - { - name_table_address = ((smsvdp->reg[0x02] & 0x0c) << 10) | 0x0700; - scroll_mod = 256; - } - else - { - name_table_address = (smsvdp->reg[0x02] << 10) & 0x3800; - scroll_mod = 224; - } - - if (IS_SMS1_VDP) - name_table_address = name_table_address & (((smsvdp->reg[0x02] & 0x01) << 10) | 0x3bff); - - /* if top 2 rows of screen not affected by horizontal scrolling, then x_scroll = 0 */ - /* else x_scroll = reg[0x08] */ - x_scroll = (((smsvdp->reg[0x00] & 0x40) && (line < 16)) ? 0 : 0x0100 - smsvdp->reg[0x08]); - - x_scroll_start_column = (x_scroll >> 3); /* x starting column tile */ - - /* Draw background layer */ - for (tile_column = 0; tile_column < 33; tile_column++) - { - UINT16 tile_data; - int tile_selected, palette_selected, horiz_selected, vert_selected, priority_select; - int tile_line; - - /* Rightmost 8 columns for SMS (or 2 columns for GG) not affected by */ - /* vertical scrolling when bit 7 of reg[0x00] is set */ - y_scroll = ((smsvdp->reg[0x00] & 0x80) && (tile_column > 23)) ? 0 : smsvdp->reg9copy; - - name_table = smsvdp->VRAM->base() + name_table_address + ((((line + y_scroll) % scroll_mod) >> 3) << 6); - - tile_line = ((tile_column + x_scroll_start_column) & 0x1f) * 2; - tile_data = name_table[tile_line] | (name_table[tile_line + 1] << 8); - - tile_selected = (tile_data & 0x01ff); - priority_select = tile_data & PRIORITY_BIT; - palette_selected = (tile_data >> 11) & 0x01; - vert_selected = (tile_data >> 10) & 0x01; - horiz_selected = (tile_data >> 9) & 0x01; - - tile_line = line - ((0x07 - (y_scroll & 0x07)) + 1); - if (vert_selected) - tile_line = 0x07 - tile_line; - - bit_plane_0 = smsvdp->VRAM->u8(((tile_selected << 5) + ((tile_line & 0x07) << 2)) + 0x00); - bit_plane_1 = smsvdp->VRAM->u8(((tile_selected << 5) + ((tile_line & 0x07) << 2)) + 0x01); - bit_plane_2 = smsvdp->VRAM->u8(((tile_selected << 5) + ((tile_line & 0x07) << 2)) + 0x02); - bit_plane_3 = smsvdp->VRAM->u8(((tile_selected << 5) + ((tile_line & 0x07) << 2)) + 0x03); - - for (pixel_x = 0; pixel_x < 8 ; pixel_x++) - { - UINT8 pen_bit_0, pen_bit_1, pen_bit_2, pen_bit_3; - UINT8 pen_selected; - - pen_bit_0 = (bit_plane_0 >> (7 - pixel_x)) & 0x01; - pen_bit_1 = (bit_plane_1 >> (7 - pixel_x)) & 0x01; - pen_bit_2 = (bit_plane_2 >> (7 - pixel_x)) & 0x01; - pen_bit_3 = (bit_plane_3 >> (7 - pixel_x)) & 0x01; - - pen_selected = (pen_bit_3 << 3 | pen_bit_2 << 2 | pen_bit_1 << 1 | pen_bit_0); - if (palette_selected) - pen_selected |= 0x10; - - - if (!horiz_selected) - { - pixel_plot_x = pixel_x; - } - else - { - pixel_plot_x = 7 - pixel_x; - } - pixel_plot_x = (0 - (x_scroll & 0x07) + (tile_column << 3) + pixel_plot_x); - if (pixel_plot_x >= 0 && pixel_plot_x < 256) - { -// logerror("%x %x\n", pixel_plot_x + pixel_offset_x, pixel_plot_y); - line_buffer[pixel_plot_x] = smsvdp->current_palette[pen_selected]; - priority_selected[pixel_plot_x] = priority_select | (pen_selected & 0x0f); - } - } - } -} - -static void sms_refresh_mode4_sprites( running_machine &machine, smsvdp_t *smsvdp, int *line_buffer, int *priority_selected, int pixel_plot_y, int line ) -{ - int sprite_index; - int pixel_x, pixel_plot_x; - int sprite_x, sprite_y, sprite_line, sprite_tile_selected, sprite_height, sprite_zoom; - int sprite_col_occurred, sprite_col_x; - int sprite_buffer[8], sprite_buffer_count, sprite_buffer_index; - int bit_plane_0, bit_plane_1, bit_plane_2, bit_plane_3; - UINT8 *sprite_table = smsvdp->VRAM->base() + ((smsvdp->reg[0x05] << 7) & 0x3f00); - - /* Draw sprite layer */ - sprite_height = (smsvdp->reg[0x01] & 0x02 ? 16 : 8); - sprite_zoom = 1; - - if (smsvdp->reg[0x01] & 0x01) /* sprite doubling */ - sprite_zoom = 2; - - sprite_buffer_count = 0; - for (sprite_index = 0; (sprite_index < 64) && (sprite_table[sprite_index] != 0xd0 || smsvdp->y_pixels != 192) && (sprite_buffer_count < 9); sprite_index++) - { - sprite_y = sprite_table[sprite_index] + 1; /* sprite y position starts at line 1 */ - - if (sprite_y > 240) - sprite_y -= 256; /* wrap from top if y position is > 240 */ - - if ((line >= sprite_y) && (line < (sprite_y + sprite_height * sprite_zoom))) - { - if (sprite_buffer_count < 8) - { - sprite_buffer[sprite_buffer_count] = sprite_index; - } - else if (line >= 0 && line < smsvdp->sms_frame_timing[ACTIVE_DISPLAY_V]) - { - /* Too many sprites per line */ - machine.scheduler().timer_set(machine.primary_screen->time_until_pos(pixel_plot_y + line, SPROVR_HPOS), FUNC(smsvdp_set_status), (int)STATUS_SPROVR, smsvdp); - } - sprite_buffer_count++; - } - } - - /* Check if display is disabled */ - if (!(smsvdp->reg[0x01] & 0x40)) - return; - - if (sprite_buffer_count > 8) - sprite_buffer_count = 8; - - memset(smsvdp->collision_buffer, 0, SMS_X_PIXELS); - sprite_buffer_count--; - - for (sprite_buffer_index = sprite_buffer_count; sprite_buffer_index >= 0; sprite_buffer_index--) - { - sprite_index = sprite_buffer[sprite_buffer_index]; - sprite_y = sprite_table[sprite_index] + 1; /* sprite y position starts at line 1 */ - - if (sprite_y > 240) - sprite_y -= 256; /* wrap from top if y position is > 240 */ - - sprite_x = sprite_table[0x80 + (sprite_index << 1)]; - - if (smsvdp->reg[0x00] & 0x08) - sprite_x -= 0x08; /* sprite shift */ - - sprite_tile_selected = sprite_table[0x81 + (sprite_index << 1)]; - - if (smsvdp->reg[0x06] & 0x04) - sprite_tile_selected += 256; /* pattern table select */ - - if (smsvdp->reg[0x01] & 0x02) - sprite_tile_selected &= 0x01fe; /* force even index */ - - sprite_line = (line - sprite_y) / sprite_zoom; - - if (sprite_line > 0x07) - sprite_tile_selected += 1; - - bit_plane_0 = smsvdp->VRAM->u8(((sprite_tile_selected << 5) + ((sprite_line & 0x07) << 2)) + 0x00); - bit_plane_1 = smsvdp->VRAM->u8(((sprite_tile_selected << 5) + ((sprite_line & 0x07) << 2)) + 0x01); - bit_plane_2 = smsvdp->VRAM->u8(((sprite_tile_selected << 5) + ((sprite_line & 0x07) << 2)) + 0x02); - bit_plane_3 = smsvdp->VRAM->u8(((sprite_tile_selected << 5) + ((sprite_line & 0x07) << 2)) + 0x03); - - sprite_col_occurred = 0; - sprite_col_x = 0; - - for (pixel_x = 0; pixel_x < 8 ; pixel_x++) - { - UINT8 pen_bit_0, pen_bit_1, pen_bit_2, pen_bit_3; - int pen_selected; - - pen_bit_0 = (bit_plane_0 >> (7 - pixel_x)) & 0x01; - pen_bit_1 = (bit_plane_1 >> (7 - pixel_x)) & 0x01; - pen_bit_2 = (bit_plane_2 >> (7 - pixel_x)) & 0x01; - pen_bit_3 = (bit_plane_3 >> (7 - pixel_x)) & 0x01; - - pen_selected = (pen_bit_3 << 3 | pen_bit_2 << 2 | pen_bit_1 << 1 | pen_bit_0) | 0x10; - - if (pen_selected == 0x10) /* Transparent palette so skip draw */ - { - continue; - } - - if (smsvdp->reg[0x01] & 0x01) - { - /* sprite doubling is enabled */ - pixel_plot_x = sprite_x + (pixel_x << 1); - - /* check to prevent going outside of active display area */ - if (pixel_plot_x < 0 || pixel_plot_x > 255) - { - continue; - } - - if (!(priority_selected[pixel_plot_x] & PRIORITY_BIT)) - { - line_buffer[pixel_plot_x] = smsvdp->current_palette[pen_selected]; - line_buffer[pixel_plot_x + 1] = smsvdp->current_palette[pen_selected]; - } - else - { - if (priority_selected[pixel_plot_x] == PRIORITY_BIT) - { - line_buffer[pixel_plot_x] = smsvdp->current_palette[pen_selected]; - } - if (priority_selected[pixel_plot_x + 1] == PRIORITY_BIT) - { - line_buffer[pixel_plot_x + 1] = smsvdp->current_palette[pen_selected]; - } - } - if (smsvdp->collision_buffer[pixel_plot_x] != 1) - { - smsvdp->collision_buffer[pixel_plot_x] = 1; - } - else - { - if (!sprite_col_occurred) - { - sprite_col_occurred = 1; - sprite_col_x = pixel_plot_x; - } - } - if (smsvdp->collision_buffer[pixel_plot_x + 1] != 1) - { - smsvdp->collision_buffer[pixel_plot_x + 1] = 1; - } - else - { - if (!sprite_col_occurred) - { - sprite_col_occurred = 1; - sprite_col_x = pixel_plot_x; - } - } - } - else - { - pixel_plot_x = sprite_x + pixel_x; - - /* check to prevent going outside of active display area */ - if (pixel_plot_x < 0 || pixel_plot_x > 255) - { - continue; - } - - if (!(priority_selected[pixel_plot_x] & PRIORITY_BIT)) - { - line_buffer[pixel_plot_x] = smsvdp->current_palette[pen_selected]; - } - else - { - if (priority_selected[pixel_plot_x] == PRIORITY_BIT) - { - line_buffer[pixel_plot_x] = smsvdp->current_palette[pen_selected]; - } - } - if (smsvdp->collision_buffer[pixel_plot_x] != 1) - { - smsvdp->collision_buffer[pixel_plot_x] = 1; - } - else - { - if (!sprite_col_occurred) - { - sprite_col_occurred = 1; - sprite_col_x = pixel_plot_x; - } - } - } - } - if (sprite_col_occurred) - machine.scheduler().timer_set(machine.primary_screen->time_until_pos(pixel_plot_y + line, SPRCOL_BASEHPOS + sprite_col_x), FUNC(smsvdp_set_status), (int)STATUS_SPRCOL, smsvdp); - } - - /* Fill column 0 with overscan color from reg[0x07] */ - if (smsvdp->reg[0x00] & 0x20) - { - line_buffer[0] = smsvdp->current_palette[BACKDROP_COLOR]; - line_buffer[1] = smsvdp->current_palette[BACKDROP_COLOR]; - line_buffer[2] = smsvdp->current_palette[BACKDROP_COLOR]; - line_buffer[3] = smsvdp->current_palette[BACKDROP_COLOR]; - line_buffer[4] = smsvdp->current_palette[BACKDROP_COLOR]; - line_buffer[5] = smsvdp->current_palette[BACKDROP_COLOR]; - line_buffer[6] = smsvdp->current_palette[BACKDROP_COLOR]; - line_buffer[7] = smsvdp->current_palette[BACKDROP_COLOR]; - } -} - - -static void sms_refresh_tms9918_sprites( running_machine &machine, smsvdp_t *smsvdp, int *line_buffer, int pixel_plot_y, int line ) -{ - int pixel_plot_x; - int sprite_col_occurred, sprite_col_x; - int sprite_height, sprite_buffer_count, sprite_index, sprite_buffer[5], sprite_buffer_index; - UINT8 *sprite_table, *sprite_pattern_table; - - /* Draw sprite layer */ - sprite_table = smsvdp->VRAM->base() + ((smsvdp->reg[0x05] & 0x7f) << 7); - sprite_pattern_table = smsvdp->VRAM->base() + ((smsvdp->reg[0x06] & 0x07) << 11); - sprite_height = 8; - - if (smsvdp->reg[0x01] & 0x02) /* Check if SI is set */ - sprite_height = sprite_height * 2; - if (smsvdp->reg[0x01] & 0x01) /* Check if MAG is set */ - sprite_height = sprite_height * 2; - - sprite_buffer_count = 0; - for (sprite_index = 0; (sprite_index < 32 * 4) && (sprite_table[sprite_index] != 0xd0) && (sprite_buffer_count < 5); sprite_index += 4) - { - int sprite_y = sprite_table[sprite_index] + 1; - - if (sprite_y > 240) - sprite_y -= 256; - - if ((line >= sprite_y) && (line < (sprite_y + sprite_height))) - { - if (sprite_buffer_count < 5) - { - sprite_buffer[sprite_buffer_count] = sprite_index; - } - else if (line >= 0 && line < smsvdp->sms_frame_timing[ACTIVE_DISPLAY_V]) - { - /* Too many sprites per line */ - machine.scheduler().timer_set(machine.primary_screen->time_until_pos(pixel_plot_y + line, SPROVR_HPOS), FUNC(smsvdp_set_status), (int)STATUS_SPROVR, smsvdp); - } - sprite_buffer_count++; - } - } - - /* Check if display is disabled */ - if (!(smsvdp->reg[0x01] & 0x40)) - return; - - if (sprite_buffer_count > 4) - sprite_buffer_count = 4; - - memset(smsvdp->collision_buffer, 0, SMS_X_PIXELS); - sprite_buffer_count--; - - for (sprite_buffer_index = sprite_buffer_count; sprite_buffer_index >= 0; sprite_buffer_index--) - { - int pen_selected; - int sprite_line, pixel_x, sprite_x, sprite_tile_selected; - int sprite_y; - UINT8 pattern; - - sprite_index = sprite_buffer[sprite_buffer_index]; - sprite_y = sprite_table[sprite_index] + 1; - - if (sprite_y > 240) - sprite_y -= 256; - - sprite_x = sprite_table[sprite_index + 1]; - pen_selected = sprite_table[sprite_index + 3] & 0x0f; - - if (IS_GAMEGEAR_VDP) - pen_selected |= 0x10; - - if (sprite_table[sprite_index + 3] & 0x80) - sprite_x -= 32; - - sprite_tile_selected = sprite_table[sprite_index + 2]; - sprite_line = line - sprite_y; - - if (smsvdp->reg[0x01] & 0x01) - sprite_line >>= 1; - - if (smsvdp->reg[0x01] & 0x02) - { - sprite_tile_selected &= 0xfc; - - if (sprite_line > 0x07) - { - sprite_tile_selected += 1; - sprite_line -= 8; - } - } - - pattern = sprite_pattern_table[sprite_tile_selected * 8 + sprite_line]; - - sprite_col_occurred = 0; - sprite_col_x = 0; - - for (pixel_x = 0; pixel_x < 8; pixel_x++) - { - if (smsvdp->reg[0x01] & 0x01) - { - pixel_plot_x = sprite_x + pixel_x * 2; - if (pixel_plot_x < 0 || pixel_plot_x > 255) - { - continue; - } - - if (pen_selected && (pattern & (1 << (7 - pixel_x)))) - { - line_buffer[pixel_plot_x] = smsvdp->current_palette[pen_selected]; - - if (smsvdp->collision_buffer[pixel_plot_x] != 1) - { - smsvdp->collision_buffer[pixel_plot_x] = 1; - } - else - { - if (!sprite_col_occurred) - { - sprite_col_occurred = 1; - sprite_col_x = pixel_plot_x; - } - } - - line_buffer[pixel_plot_x+1] = smsvdp->current_palette[pen_selected]; - - if (smsvdp->collision_buffer[pixel_plot_x + 1] != 1) - { - smsvdp->collision_buffer[pixel_plot_x + 1] = 1; - } - else - { - if (!sprite_col_occurred) - { - sprite_col_occurred = 1; - sprite_col_x = pixel_plot_x; - } - } - } - } - else - { - pixel_plot_x = sprite_x + pixel_x; - - if (pixel_plot_x < 0 || pixel_plot_x > 255) - { - continue; - } - - if (pen_selected && (pattern & (1 << (7 - pixel_x)))) - { - line_buffer[pixel_plot_x] = smsvdp->current_palette[pen_selected]; - - if (smsvdp->collision_buffer[pixel_plot_x] != 1) - { - smsvdp->collision_buffer[pixel_plot_x] = 1; - } - else - { - if (!sprite_col_occurred) - { - sprite_col_occurred = 1; - sprite_col_x = pixel_plot_x; - } - } - } - } - } - - if (smsvdp->reg[0x01] & 0x02) - { - sprite_tile_selected += 2; - pattern = sprite_pattern_table[sprite_tile_selected * 8 + sprite_line]; - sprite_x += (smsvdp->reg[0x01] & 0x01 ? 16 : 8); - - for (pixel_x = 0; pixel_x < 8; pixel_x++) - { - if (smsvdp->reg[0x01] & 0x01) - { - pixel_plot_x = sprite_x + pixel_x * 2; - - if (pixel_plot_x < 0 || pixel_plot_x > 255) - { - continue; - } - - if (pen_selected && (pattern & (1 << (7 - pixel_x)))) - { - line_buffer[pixel_plot_x] = smsvdp->current_palette[pen_selected]; - - if (smsvdp->collision_buffer[pixel_plot_x] != 1) - { - smsvdp->collision_buffer[pixel_plot_x] = 1; - } - else - { - if (!sprite_col_occurred) - { - sprite_col_occurred = 1; - sprite_col_x = pixel_plot_x; - } - } - - line_buffer[pixel_plot_x+1] = smsvdp->current_palette[pen_selected]; - - if (smsvdp->collision_buffer[pixel_plot_x + 1] != 1) - { - smsvdp->collision_buffer[pixel_plot_x + 1] = 1; - } - else - { - if (!sprite_col_occurred) - { - sprite_col_occurred = 1; - sprite_col_x = pixel_plot_x; - } - } - } - } - else - { - pixel_plot_x = sprite_x + pixel_x; - - if (pixel_plot_x < 0 || pixel_plot_x > 255) - { - continue; - } - - if (pen_selected && (pattern & (1 << (7 - pixel_x)))) - { - line_buffer[pixel_plot_x] = smsvdp->current_palette[pen_selected]; - - if (smsvdp->collision_buffer[pixel_plot_x] != 1) - { - smsvdp->collision_buffer[pixel_plot_x] = 1; - } - else - { - if (!sprite_col_occurred) - { - sprite_col_occurred = 1; - sprite_col_x = pixel_plot_x; - } - } - } - } - } - } - if (sprite_col_occurred) - machine.scheduler().timer_set(machine.primary_screen->time_until_pos(pixel_plot_y + line, SPRCOL_BASEHPOS + sprite_col_x), FUNC(smsvdp_set_status), (int)STATUS_SPRCOL, smsvdp); - } -} - - -static void sms_refresh_line_mode2( smsvdp_t *smsvdp, int *line_buffer, int line ) -{ - int tile_column; - int pixel_x, pixel_plot_x; - UINT8 *name_table, *color_table, *pattern_table; - int pattern_mask, color_mask, pattern_offset; - - /* Draw background layer */ - name_table = smsvdp->VRAM->base() + ((smsvdp->reg[0x02] & 0x0f) << 10) + ((line >> 3) * 32); - color_table = smsvdp->VRAM->base() + ((smsvdp->reg[0x03] & 0x80) << 6); - color_mask = ((smsvdp->reg[0x03] & 0x7f) << 3) | 0x07; - pattern_table = smsvdp->VRAM->base() + ((smsvdp->reg[0x04] & 0x04) << 11); - pattern_mask = ((smsvdp->reg[0x04] & 0x03) << 8) | 0xff; - pattern_offset = (line & 0xc0) << 2; - - for (tile_column = 0; tile_column < 32; tile_column++) - { - UINT8 pattern; - UINT8 colors; - - pattern = pattern_table[(((pattern_offset + name_table[tile_column]) & pattern_mask) * 8) + (line & 0x07)]; - colors = color_table[(((pattern_offset + name_table[tile_column]) & color_mask) * 8) + (line & 0x07)]; - - for (pixel_x = 0; pixel_x < 8; pixel_x++) - { - UINT8 pen_selected; - - if (pattern & (1 << (7 - pixel_x))) - { - pen_selected = colors >> 4; - } - else - { - pen_selected = colors & 0x0f; - } - - if (!pen_selected) - pen_selected = BACKDROP_COLOR; - - pixel_plot_x = (tile_column << 3) + pixel_x; - - if (IS_GAMEGEAR_VDP) - pen_selected |= 0x10; - - line_buffer[pixel_plot_x] = smsvdp->current_palette[pen_selected]; - } - } -} - - -static void sms_refresh_line_mode0( smsvdp_t *smsvdp, int *line_buffer, int line) -{ - int tile_column; - int pixel_x, pixel_plot_x; - UINT8 *name_table, *color_table, *pattern_table; - - /* Draw background layer */ - name_table = smsvdp->VRAM->base() + ((smsvdp->reg[0x02] & 0x0f) << 10) + ((line >> 3) * 32); - color_table = smsvdp->VRAM->base() + ((smsvdp->reg[0x03] << 6) & (VRAM_SIZE - 1)); - pattern_table = smsvdp->VRAM->base() + ((smsvdp->reg[0x04] << 11) & (VRAM_SIZE - 1)); - - for (tile_column = 0; tile_column < 32; tile_column++) - { - UINT8 pattern; - UINT8 colors; - - pattern = pattern_table[(name_table[tile_column] * 8) + (line & 0x07)]; - colors = color_table[name_table[tile_column] >> 3]; - - for (pixel_x = 0; pixel_x < 8; pixel_x++) - { - int pen_selected; - - if (pattern & (1 << (7 - pixel_x))) - pen_selected = colors >> 4; - else - pen_selected = colors & 0x0f; - - if (IS_GAMEGEAR_VDP) - pen_selected |= 0x10; - - pixel_plot_x = (tile_column << 3) + pixel_x; - line_buffer[pixel_plot_x] = smsvdp->current_palette[pen_selected]; - } - } -} - - -static void sms_refresh_line( running_machine &machine, smsvdp_t *smsvdp, bitmap_t *bitmap, int pixel_offset_x, int pixel_plot_y, int line ) -{ - int x; - int *blitline_buffer = smsvdp->line_buffer; - int priority_selected[256]; - - switch( smsvdp->vdp_mode ) - { - case 0: - if (line >= 0 && line < smsvdp->sms_frame_timing[ACTIVE_DISPLAY_V]) - sms_refresh_line_mode0(smsvdp, blitline_buffer, line); - sms_refresh_tms9918_sprites(machine, smsvdp, blitline_buffer, pixel_plot_y, line); - break; - - case 2: - if (line >= 0 && line < smsvdp->sms_frame_timing[ACTIVE_DISPLAY_V]) - sms_refresh_line_mode2(smsvdp, blitline_buffer, line); - sms_refresh_tms9918_sprites(machine, smsvdp, blitline_buffer, pixel_plot_y, line); - break; - - case 4: - default: - memset(priority_selected, 0, sizeof(priority_selected)); - if (line >= 0 && line < smsvdp->sms_frame_timing[ACTIVE_DISPLAY_V]) - sms_refresh_line_mode4(smsvdp, blitline_buffer, priority_selected, line); - sms_refresh_mode4_sprites(machine, smsvdp, blitline_buffer, priority_selected, pixel_plot_y, line); - break; - } - - /* Check if display is disabled or we're below/above active area */ - if (!(smsvdp->reg[0x01] & 0x40) || line < 0 || line >= smsvdp->sms_frame_timing[ACTIVE_DISPLAY_V]) - { - for (x = 0; x < 256; x++) - { - blitline_buffer[x] = smsvdp->current_palette[BACKDROP_COLOR]; - } - } - - if (IS_GAMEGEAR_VDP && smsvdp->gg_sms_mode) - { - int *combineline_buffer = smsvdp->line_buffer + ((line & 0x03) + 1) * 256; - int plot_x = 48; - - /* Do horizontal scaling */ - for (x = 8; x < 248;) - { - int combined; - - /* Take red and green from first pixel, and blue from second pixel */ - combined = (blitline_buffer[x] & 0x00ff) | (blitline_buffer[x + 1] & 0x0f00); - combineline_buffer[plot_x] = combined; - - /* Take red from second pixel, and green and blue from third pixel */ - combined = (blitline_buffer[x + 1] & 0x000f) | (blitline_buffer[x + 2] & 0x0ff0); - combineline_buffer[plot_x + 1] = combined; - x += 3; - plot_x += 2; - } - - /* Do vertical scaling for a screen with 192 or 224 lines - Lines 0-2 and 221-223 have no effect on the output on the GG screen. - We will calculate the gamegear lines as follows: - GG_0 = 1/6 * SMS_3 + 1/3 * SMS_4 + 1/3 * SMS_5 + 1/6 * SMS_6 - GG_1 = 1/6 * SMS_4 + 1/3 * SMS_5 + 1/3 * SMS_6 + 1/6 * SMS_7 - GG_2 = 1/6 * SMS_6 + 1/3 * SMS_7 + 1/3 * SMS_8 + 1/6 * SMS_9 - GG_3 = 1/6 * SMS_7 + 1/3 * SMS_8 + 1/3 * SMS_9 + 1/6 * SMS_10 - GG_4 = 1/6 * SMS_9 + 1/3 * SMS_10 + 1/3 * SMS_11 + 1/6 * SMS_12 - ..... - GG_142 = 1/6 * SMS_216 + 1/3 * SMS_217 + 1/3 * SMS_218 + 1/6 * SMS_219 - GG_143 = 1/6 * SMS_217 + 1/3 * SMS_218 + 1/3 * SMS_219 + 1/6 * SMS_220 - */ - { - int gg_line; - int my_line = pixel_plot_y + line - (TBORDER_START + NTSC_224_TBORDER_Y_PIXELS); - int *line1, *line2, *line3, *line4; - - /* First make sure there's enough data to draw anything */ - /* We need one more line of data if we're on line 8, 11, 14, 17, etc */ - if (my_line < 6 || my_line > 220 || ((my_line - 8) % 3 == 0)) - { - return; - } - - gg_line = ((my_line - 6) / 3) * 2; - - /* If we're on SMS line 7, 10, 13, etc we're on an odd GG line */ - if (my_line % 3) - { - gg_line++; - } - - /* Calculate the line we will be drawing on */ - pixel_plot_y = TBORDER_START + NTSC_192_TBORDER_Y_PIXELS + 24 + gg_line; - - /* Setup our source lines */ - line1 = smsvdp->line_buffer + (((my_line - 3) & 0x03) + 1) * 256; - line2 = smsvdp->line_buffer + (((my_line - 2) & 0x03) + 1) * 256; - line3 = smsvdp->line_buffer + (((my_line - 1) & 0x03) + 1) * 256; - line4 = smsvdp->line_buffer + (((my_line - 0) & 0x03) + 1) * 256; - - for (x = 0 + 48; x < 160 + 48; x++) - { - rgb_t c1 = machine.pens[line1[x]]; - rgb_t c2 = machine.pens[line2[x]]; - rgb_t c3 = machine.pens[line3[x]]; - rgb_t c4 = machine.pens[line4[x]]; - *BITMAP_ADDR32(bitmap, pixel_plot_y, pixel_offset_x + x) = - MAKE_RGB((RGB_RED(c1) / 6 + RGB_RED(c2) / 3 + RGB_RED(c3) / 3 + RGB_RED(c4) / 6 ), - (RGB_GREEN(c1) / 6 + RGB_GREEN(c2) / 3 + RGB_GREEN(c3) / 3 + RGB_GREEN(c4) / 6 ), - (RGB_BLUE(c1) / 6 + RGB_BLUE(c2) / 3 + RGB_BLUE(c3) / 3 + RGB_BLUE(c4) / 6 ) ); - } - return; - } - blitline_buffer = combineline_buffer; - } - - for (x = 0; x < 256; x++) - { - *BITMAP_ADDR32(bitmap, pixel_plot_y + line, pixel_offset_x + x) = machine.pens[blitline_buffer[x]]; - } -} - - -// This is only used by Light Phaser. Should it be moved elsewhere? -int sms_vdp_check_brightness(device_t *device, int x, int y) -{ - /* brightness of the lightgray color in the frame drawn by Light Phaser games */ - const UINT8 sensor_min_brightness = 0x7f; - - /* TODO: Check how Light Phaser behaves for border areas. For Gangster Town, should */ - /* a shot at right border (HC~=0x90) really appear at active scr, near to left border? */ - if (x < LBORDER_START + LBORDER_X_PIXELS || x >= LBORDER_START + LBORDER_X_PIXELS + 256) - return 0; - - smsvdp_t *smsvdp = get_safe_token(device); - rgb_t color = *BITMAP_ADDR32(smsvdp->tmpbitmap, y, x); - - /* reference: http://www.w3.org/TR/AERT#color-contrast */ - UINT8 brightness = (RGB_RED(color) * 0.299) + (RGB_GREEN(color) * 0.587) + (RGB_BLUE(color) * 0.114); - //printf ("color brightness: %2X for x %d y %d\n", brightness, x, y); - - return (brightness >= sensor_min_brightness) ? 1 : 0; -} - - -static void sms_update_palette( smsvdp_t *smsvdp ) -{ - int i; - - /* Exit if palette is has no changes */ - if (smsvdp->cram_dirty == 0) - { - return; - } - smsvdp->cram_dirty = 0; - - if (smsvdp->vdp_mode != 4 && ! IS_GAMEGEAR_VDP) - { - for(i = 0; i < 16; i++) - { - smsvdp->current_palette[i] = 64 + i; - } - return; - } - - if (IS_GAMEGEAR_VDP) - { - if (smsvdp->gg_sms_mode) - { - for (i = 0; i < 32; i++) - { - smsvdp->current_palette[i] = ((smsvdp->CRAM->u8(i) & 0x30) << 6) | ((smsvdp->CRAM->u8(i) & 0x0c ) << 4) | ((smsvdp->CRAM->u8(i) & 0x03) << 2); - } - } - else - { - for (i = 0; i < 32; i++) - { - smsvdp->current_palette[i] = ((smsvdp->CRAM->u8(i * 2 + 1) << 8) | smsvdp->CRAM->u8(i * 2)) & 0x0fff; - } - } - } - else - { - for (i = 0; i < 32; i++) - { - smsvdp->current_palette[i] = smsvdp->CRAM->u8(i) & 0x3f; - } - } -} - - -UINT32 sms_vdp_update( device_t *device, bitmap_t *bitmap, const rectangle *cliprect ) -{ - smsvdp_t *smsvdp = get_safe_token(device); - copybitmap(bitmap, smsvdp->tmpbitmap, 0, 0, 0, 0, cliprect); - return 0; -} - - -/***************************************************************************** - DEVICE INTERFACE -*****************************************************************************/ - -static DEVICE_START( smsvdp ) -{ - smsvdp_t *smsvdp = get_safe_token(device); - const smsvdp_interface *intf = get_interface(device); - - screen_device *screen = device->machine().first_screen(); - int width = screen->width(); - int height = screen->height(); - - smsvdp->features = intf->model; - smsvdp->int_callback = intf->int_callback; - smsvdp->pause_callback = intf->pause_callback; - - /* Allocate video RAM */ - smsvdp->VRAM = device->machine().region_alloc("vdp_vram", VRAM_SIZE, 1, ENDIANNESS_LITTLE); - smsvdp->CRAM = device->machine().region_alloc("vdp_cram", MAX_CRAM_SIZE, 1, ENDIANNESS_LITTLE); - smsvdp->line_buffer = auto_alloc_array(device->machine(), int, 256 * 5); - - smsvdp->collision_buffer = auto_alloc_array(device->machine(), UINT8, SMS_X_PIXELS); - smsvdp->sms_frame_timing = auto_alloc_array(device->machine(), UINT8, 7); - - /* Make temp bitmap for rendering */ - smsvdp->tmpbitmap = auto_bitmap_alloc(device->machine(), width, height, BITMAP_FORMAT_INDEXED32); - - smsvdp->smsvdp_display_timer = device->machine().scheduler().timer_alloc(FUNC(smsvdp_display_callback), smsvdp); - smsvdp->smsvdp_display_timer->adjust(screen->time_until_pos(0, DISPLAY_CB_HPOS), 0, screen->scan_period()); - - device->save_item(NAME(smsvdp->status)); - device->save_item(NAME(smsvdp->reg9copy)); - device->save_item(NAME(smsvdp->addrmode)); - device->save_item(NAME(smsvdp->addr)); - device->save_item(NAME(smsvdp->cram_mask)); - device->save_item(NAME(smsvdp->cram_dirty)); - device->save_item(NAME(smsvdp->pending)); - device->save_item(NAME(smsvdp->buffer)); - device->save_item(NAME(smsvdp->gg_sms_mode)); - device->save_item(NAME(smsvdp->irq_state)); - device->save_item(NAME(smsvdp->vdp_mode)); - device->save_item(NAME(smsvdp->y_pixels)); - device->save_item(NAME(smsvdp->line_counter)); - device->save_item(NAME(smsvdp->hcounter)); - device->save_item(NAME(smsvdp->reg)); - device->save_item(NAME(smsvdp->current_palette)); - device->save_pointer(NAME(smsvdp->line_buffer), 256 * 5); - device->save_pointer(NAME(smsvdp->collision_buffer), SMS_X_PIXELS); - device->save_item(NAME(*smsvdp->tmpbitmap)); -} - -static DEVICE_RESET( smsvdp ) -{ - smsvdp_t *smsvdp = get_safe_token(device); - int i; - - /* Most register are 0x00 at power-up */ - for (i = 0; i < NUM_OF_REGISTER; i++) - smsvdp->reg[i] = 0x00; - - smsvdp->reg[0x02] = 0x0e; - smsvdp->reg[0x0a] = 0xff; - - smsvdp->status = 0; - smsvdp->reg9copy = 0; - smsvdp->addrmode = 0; - smsvdp->addr = 0; - smsvdp->gg_sms_mode = 0; - smsvdp->cram_mask = (IS_GAMEGEAR_VDP && !smsvdp->gg_sms_mode) ? (GG_CRAM_SIZE - 1) : (SMS_CRAM_SIZE - 1); - smsvdp->cram_dirty = 1; - smsvdp->pending = 0; - smsvdp->buffer = 0; - smsvdp->irq_state = 0; - smsvdp->line_counter = 0; - smsvdp->hcounter = 0; - - for (i = 0; i < 0x20; i++) - smsvdp->current_palette[i] = 0; - - set_display_settings(device); - - /* Clear RAM */ - memset(smsvdp->VRAM->base(), 0, VRAM_SIZE); - memset(smsvdp->CRAM->base(), 0, MAX_CRAM_SIZE); - memset(smsvdp->line_buffer, 0, 256 * 5 * sizeof(int)); -} - -DEVICE_GET_INFO( smsvdp ) -{ - switch (state) - { - /* --- the following bits of info are returned as 64-bit signed integers --- */ - case DEVINFO_INT_TOKEN_BYTES: info->i = sizeof(smsvdp_t); break; - - /* --- the following bits of info are returned as pointers to data or functions --- */ - case DEVINFO_FCT_START: info->start = DEVICE_START_NAME(smsvdp); break; - case DEVINFO_FCT_STOP: /* Nothing */ break; - case DEVINFO_FCT_RESET: info->reset = DEVICE_RESET_NAME(smsvdp); break; - - /* --- the following bits of info are returned as NULL-terminated strings --- */ - case DEVINFO_STR_NAME: strcpy(info->s, "Sega Master SYstem / Game Gear VDP"); break; - case DEVINFO_STR_FAMILY: strcpy(info->s, "Sega MS VDP"); break; - case DEVINFO_STR_VERSION: strcpy(info->s, "1.0"); break; - case DEVINFO_STR_SOURCE_FILE: strcpy(info->s, __FILE__); break; - case DEVINFO_STR_CREDITS: strcpy(info->s, "Copyright MAME / MESS Team"); break; - } -} - -DEFINE_LEGACY_DEVICE(SMSVDP, smsvdp); diff --git a/src/mame/video/smsvdp.h b/src/mame/video/smsvdp.h deleted file mode 100644 index 92a20832e54..00000000000 --- a/src/mame/video/smsvdp.h +++ /dev/null @@ -1,86 +0,0 @@ -/************************************************************************* - - smsvdp.h - - Implementation of Sega VDP chip used in Master System and Game Gear - -**************************************************************************/ - -#ifndef __SMSVDP_H__ -#define __SMSVDP_H__ - -#include "devcb.h" - - -/*************************************************************************** - CONSTANTS -***************************************************************************/ - - -#define MODEL_315_5124 0x0001 -#define MODEL_315_5246 0x0002 -#define MODEL_315_5378 0x0004 - -#define SMS_X_PIXELS 342 /* 342 pixels */ -#define NTSC_Y_PIXELS 262 /* 262 lines */ -#define PAL_Y_PIXELS 313 /* 313 lines */ -#define LBORDER_START (1 + 2 + 14 + 8) -#define LBORDER_X_PIXELS (0x0d) /* 13 pixels */ -#define RBORDER_X_PIXELS (0x0f) /* 15 pixels */ -#define TBORDER_START (3 + 13) -#define NTSC_192_TBORDER_Y_PIXELS (0x1b) /* 27 lines */ -#define NTSC_192_BBORDER_Y_PIXELS (0x18) /* 24 lines */ -#define NTSC_224_TBORDER_Y_PIXELS (0x0b) /* 11 lines */ -#define NTSC_224_BBORDER_Y_PIXELS (0x08) /* 8 lines */ -#define PAL_192_TBORDER_Y_PIXELS (0x36) /* 54 lines */ -#define PAL_192_BBORDER_Y_PIXELS (0x30) /* 48 lines */ -#define PAL_224_TBORDER_Y_PIXELS (0x26) /* 38 lines */ -#define PAL_224_BBORDER_Y_PIXELS (0x20) /* 32 lines */ -#define PAL_240_TBORDER_Y_PIXELS (0x1e) /* 30 lines */ -#define PAL_240_BBORDER_Y_PIXELS (0x18) /* 24 lines */ - - -/*************************************************************************** - TYPE DEFINITIONS -***************************************************************************/ - -typedef void (*smsvdp_int_cb)( running_machine &machine, int state ); -typedef void (*smsvdp_pause_cb)( running_machine &machine ); - -typedef struct _smsvdp_interface smsvdp_interface; -struct _smsvdp_interface -{ - UINT32 model; /* Select model/features for the emulation */ - smsvdp_int_cb int_callback; /* Interrupt callback function */ - smsvdp_pause_cb pause_callback; /* Pause callback function */ -}; - -/*************************************************************************** - DEVICE CONFIGURATION MACROS -***************************************************************************/ - -DECLARE_LEGACY_DEVICE(SMSVDP, smsvdp); - -#define MCFG_SMSVDP_ADD(_tag, _interface) \ - MCFG_DEVICE_ADD(_tag, SMSVDP, 0) \ - MCFG_DEVICE_CONFIG(_interface) - - -/*************************************************************************** - DEVICE I/O FUNCTIONS -***************************************************************************/ - -/* prototypes */ - -UINT32 sms_vdp_update( device_t *device, bitmap_t *bitmap, const rectangle *cliprect ); -READ8_DEVICE_HANDLER( sms_vdp_vcount_r ); -READ8_DEVICE_HANDLER( sms_vdp_hcount_latch_r ); -WRITE8_DEVICE_HANDLER( sms_vdp_hcount_latch_w ); -READ8_DEVICE_HANDLER( sms_vdp_data_r ); -WRITE8_DEVICE_HANDLER( sms_vdp_data_w ); -READ8_DEVICE_HANDLER( sms_vdp_ctrl_r ); -WRITE8_DEVICE_HANDLER( sms_vdp_ctrl_w ); -void sms_vdp_set_ggsmsmode( device_t *device, int mode ); -int sms_vdp_check_brightness( device_t *device, int x, int y ); - -#endif /* __SMSVDP_H__ */