diff options
Diffstat (limited to 'src/mame/drivers/segae.c')
-rw-r--r-- | src/mame/drivers/segae.c | 2398 |
1 files changed, 2398 insertions, 0 deletions
diff --git a/src/mame/drivers/segae.c b/src/mame/drivers/segae.c new file mode 100644 index 00000000000..957e266752b --- /dev/null +++ b/src/mame/drivers/segae.c @@ -0,0 +1,2398 @@ +/* + +Sega System E +-- this is a modified version of the sms.c from HazeMD + it really needs some improvements + + + Sega System 'E' is a piece of hardware used for a couple of Arcade Games + produced by Sega in the Mid 80's, its roughly based on their Sega Master System + home console unit, using the same '315-5124' VDP (actually in this case 2 of + them) + + An interesting feature of the system is that the CPU is contained on the ROM + board, the MAIN System E board contains the Graphics processor, this opens the + possibility for using processors other than the Standard Z80 to run the main + game code on; several games have an encrypted Z80 module instead. + + Also interesting is each VDP has double the Video RAM found on the SMS console + this is banked through Port Writes, the System also allows for the Video RAM + to be written directly, bypassing the usual procedure of writing to it via the + '315-5124' data port, it can not however be read directly, the same area used + for writing is used to access banked ROMs when reading + + Pretty much everything on this hardware is done through port accesses, the + main memory map consists of simply ROM, BANKED ROM / BANKED RAM, RAM + +******************************************************************************** + + ROMs + CPU Board (32kb ROMs) + + IC 07 (Good) IC 05 (Good) + IC 04 (Good) IC 03 (Good) + IC 02 (Good) + + (834-5803) MAIN Board (8kb RAMs) + + IC 49 (Good) IC 55 (Good) System RAM (0xc000 - 0xffff) + IC 03 (Good) IC 07 (Good) Front Layer VRAM (Bank 1) Port F7 -0------ + IC 04 (Good) IC 08 (Good) Front Layer VRAM (Bank 2) Port F7 -1------ + IC 01 (Good) IC 05 (Good) Back Layer VRAM (Bank 1) Port F7 0------- + IC 02 (Good) IC 06 (Good) Back Layer VRAM (Bank 2) Port F7 1------- + (or at least this is how it appears from HangOnJr's RAMs Test) + + 2x (315-5124)'s here too, these are the VDP chips + + PORTS (to be completed) + + 0xba - 0xbb r/w Back Layer VDP + 0xbe - 0xbf r/w Front Layer VDP + + 0xf7 w/o Banking Controls + + 0xe0 r/o Inputs (Coins, Start Btns) + 0xe1 r/o Controls (Transformer) + + 0xf2 - 0xf3 r/o Dipswitches + + 0xf8 r/o Analog Input (Hang On Jr) + + 0x7e r/o V Counter (vertical beam pos in scanlines) + 0x7f r/o H Counter (horizontal beam pos in 'pixel clock cycles') + +******************************************************************************** + +Sega System E Hardware Overview +Sega, 1985-1988 + +This PCB is essentially a Sega Master System home console unit, but using +two '315-5124' VDPs and extra RAM. +The CPU is located on a plug-in board that also holds all of the EPROMs. + +The games that run on this hardware include.... +Hang-On Jr. 1985 +Transformer/Astro Flash 1986 +Riddle of Pythagoras 1986 +Opa Opa 1987 +Fantasy Zone 2 1988 +Tetris 1988 + +PCB Layout +---------- +834-5803 (C)Sega 1985 +|-----------------------------------------------------| +| D4168 D4168 D4168 D4168 | +| | +| D4168 D4168 D4168 D4168 | +| | +| | +| SW1 | +|CN1 | +| SW2 | +| | +| LED |---| |---| | +| | 3 | | 3 | | +| | 1 | | 1 | | +| | 5 | | 5 | | +| | | | | | | CN3| +| | 5 | | 5 | 8255 | +|CN4 | 1 | | 1 | | +| | 2 | | 2 | | +| | 4 | | 4 | | +| |---| |---| | +| |--------ROM-BOARD-(above)---------| | +| | | | +| |CN2 10.7386MHz | | +| | D4168 | | +| VOL | D4168 | | +| LA4460 |----------------------------------| | +|-----------------------------------------------------| +Notes: + 315-5124 VDP clock - 10.7386MHz + SN76496 clock - 3.579533MHz [10.7386/3] + D4168 - 8k x8 SRAM + VSync - 60Hz + HSync - 15.58kHz + CN1 - Connector used for standard controls + CN2 - connector for CPU/ROM PCB + CN3 - Connector used for special controls (via a small plug-in interface PCB) + CN4 - Connector for power + +ROM Daughterboard +----------------- +834-6592-01 +|--------------------------------------------| +| | +| |---| | +|C | | IC6 | +|N |Z80| | +|2 | | | +| | | IC2 IC3 IC4 IC5 IC7| +| |---| | +| IC1 PAD1 PAD2 PAD3 PAD4| +|--------------------------------------------| +Notes: + IC1: Z80 clock - 5.3693MHz [10.7386/2] + On some games this is replaced with a NEC MC-8123 Encrypted CPU Module. + The clock speed is the same. The MC-8123 contains a Z80 core, plus a RAM chip + and battery. When the battery dies, the program can no longer be decrypted + and the PCB does not boot up at all. The battery can not be changed because the + MC-8123 is sealed, so there is no way to access it. + + IC2 - IC5: 27C256 EPROM (DIP28) + + IC6: 74LS139 + + IC7: 27C256 EPROM (DIP28) + + PAD1-4: These are jumper pads used to configure the ROM board for use with the + Z80 or with the MC8123 CPU. + PAD1 - Ties Z80 pin 24 (WAIT) to pin1 of the EPROMs at IC2, 3, 4 & 5 + PAD2 - Ties CN2 pin B21 to pin1 of the EPROMs at IC2, 3, 4 & 5 + PAD3 - Ties CN2 pin B21 to pin 2 of the 74LS139 @ IC6 + PAD4 - Ties Z80 pin 24 (WAIT) to pin 2 of the 74LS139 @ IC6 + + The pads are configured like this..... (U=Upper, L=Lower) + + |----| |----| + |IC6 | |IC7 | + | 12|------|22 | + | | | | + IC2 IC3 IC4 IC5 | 1|------|27 | + PIN1 PIN1 PIN1 PIN1 | 2|--| | | + O-----O--+---O------O |----| | |----| + | | + | |----| | + O--+----O | O |---O + CN2 Z80 PAD1U PAD2U | PAD3U | PAD4U + B21 PIN24 PAD1L PAD2L | PAD3L | PAD4L + O O--4.7k--O O----| O----| O + | | | | + | |-------|------------------| + | | + |------------------------| + + When using a regular Z80B (and thus, unencrypted code): + PAD1 - Open + PAD2 - Open + PAD3 - Shorted + PAD4 - Open + + When using an encrypted CPU module (MC-8123): + PAD1 - Open + PAD2 - Shorted + PAD3 - Open + PAD4 - Open + Additionally, a wire must be tied from CN2 pin B22 to the side + of PAD3 nearest IC6 (i.e. PAD3U). + +ROMs: +----- + +Game IC2 IC3 IC4 IC5 IC7 +--------------------------------------------------------------------------------- +Hang-On Jr. EPR-? EPR-? EPR-? EPR-? EPR-? Hello, Sega Part Numbers....!? +Transformer EPR-7350 EPR-? EPR-7348 EPR-7347 EPR-? Ditto + /Astro Flash EPR-7350 EPR-7349 EPR-7348 EPR-7347 EPR-7723 +Riddle of Pythagoras EPR-10422 EPR-10423 EPR-10424 EPR-10425 EPR-10426 +Opa Opa EPR-11220 EPR-11221 EPR-11222 EPR-11223 EPR-11224 +Fantasy Zone 2 EPR-11412 EPR-11413 EPR-11414 EPR-11415 EPR-11416 +Tetris - - EPR-12211 EPR-12212 EPR-12213 + +A System E PCB can run all of the games simply by swapping the EPROMs plus CPU. +Well, in theory anyway. To run the not-encrypted games, just swap EPROMs and they will work. + +To run the encrypted games, use a double sized EPROM in IC7 (i.e. a 27C512) +and program the decrypted opcodes to the lower half and the decrypted data to the upper half, +then connect the highest address pin of the EPROM (A15 pin 1) to the M1 pin on the Z80. +This method has been tested and does not actually work. An update on this may follow.... + + +System E PCB Pinout +------------------- + +CN1 +--- + ++12V 1A 1B Coin switch 1 +Coin switch 2 2A 2B Test switch +Service switch 3A 3B + 4A 4B 1P start +2P start 5A 5B 1P up +1P down 6A 6B 1P left +1P right 7A 7B 1P button 1 +1P button 2 8A 8B + 9A 9B 2P up +2P down 10A 10B 2P left +2P RIGHT 11A 11B 2P button 1 +2P button 2 12A 12B + 13A 13B Video RED + 14A 14B Video GREEN + 15A 15B Video BLUE + 16A 16B Video SYNC + 17A 17B + 18A 18B +Speaker [+] 19A 19B +Speaker [-] 20A 20B +Coin counter GND 21A 21B +GND 22A 22B Coin counter 1 + 23A 23B Coin counter 2 + 24A 24B + 25A 25B +CN4 +--- + ++5V 1A 1B +5V ++5V 2A 2B +5V + 3A 3B +GND 4A 4B GND +GND 5A 5B GND ++12V 6A 6B +12V ++12V 7A 7B +12V +GND 8A 8B GND + + + Game Notes: + Riddle of Pythagoras is interesting, it looks like Sega might have planned it + as a two player game, there is prelimiary code for 2 player support which + never gets executed, see code around 0x0E95. Theres also quite a bit of + pointless code here and there. Some Interesting Memory Locations + + C000 : level - value (00-0x32) + C001 : level - display (00-0x50, BCD coded) + C003 : credits (00-0x99, BCD coded) + C005 : DSWA put here (coinage, left and right nibbles for left and right slot + - freeplay when 0x0f or 0xf0) + C006 : DSWB put here + bits 0 and 1 : lives ("02", "03", "04", "98") + bit 3 : difficulty + bits 5 and 6 : bonus lives ("50K, 100K, 200K, 500K", "100K, 200K, 500K", "100K, + 200K, 500K, 99999999", "none") + C009 : lives (for player 1) + C00A : lives (for player 2) + C00B : bonus lives counter + + E20B-E20E : score (00000000-0x99999999, BCD coded) + E215-E218 : hi-score (00000000-0x99999999, BCD coded) + + E543 : bit 0 : ON = player 1 one still has lives + bit 1 : ON = player 2 one still has lives + bit 2 : ON = player 1 is the current player - OFF = player 2 is the + current player + + E572 : table with L. slot infos (5 bytes wide) + E577 : table with R. slot infos (5 bytes wide) + +Known issues: + +sometimes hangonjr has corrupt gfx when you start a game, I don't know why + +todo: + +tidy up, add save states, clean up so we can use it with hazemd again +add emulation of vdp bugs, use mame's new screen timing system instead +covert megatech / megaplay drivers to use new code etc. etc. + +*/ + +#include "driver.h" +#include "sound/sn76496.h" +#include "machine/mc8123.h" +#include "machine/segacrpt.h" +#include "segae.h" + + +//static UINT8* sms_rom; +static UINT8* sms_mainram; +//static UINT8* smsgg_backupram; +static TIMER_CALLBACK_PTR( sms_scanline_timer_callback ); +static struct sms_vdp *vdp2; +static struct sms_vdp *vdp1; + +static struct sms_vdp *md_sms_vdp; + +/* All Accesses to VRAM go through here for safety */ +#define SMS_VDP_VRAM(address) chip->vram[(address)&0x3fff] + +#ifdef UNUSED_FUNCTION +static ADDRESS_MAP_START( sms_readmem, ADDRESS_SPACE_PROGRAM, 8 ) +// AM_RANGE(0x0000 , 0xbfff) AM_READ(MRA8_ROM) +// AM_RANGE(0xc000 , 0xdfff) AM_READ(MRA8_RAM) AM_MIRROR(0x2000) +ADDRESS_MAP_END + +static ADDRESS_MAP_START( sms_writemem, ADDRESS_SPACE_PROGRAM, 8 ) +// AM_RANGE(0x0000 , 0xbfff) AM_WRITE(MWA8_ROM) +// AM_RANGE(0xc000 , 0xdfff) AM_WRITE(MWA8_RAM) AM_MIRROR(0x2000) +ADDRESS_MAP_END +#endif + +/* we have to fill in the ROM addresses for systeme due to the encrypted games */ +static ADDRESS_MAP_START( systeme_readmem, ADDRESS_SPACE_PROGRAM, 8 ) + AM_RANGE(0x0000, 0x7fff) AM_READ(MRA8_ROM) /* Fixed ROM */ + AM_RANGE(0x8000, 0xbfff) AM_READ(MRA8_BANK1) /* Banked ROM */ + +// AM_RANGE(0x0000 , 0xbfff) AM_READ(MRA8_ROM) +// AM_RANGE(0xc000 , 0xdfff) AM_READ(MRA8_RAM) AM_MIRROR(0x2000) +ADDRESS_MAP_END + +static ADDRESS_MAP_START( systeme_writemem, ADDRESS_SPACE_PROGRAM, 8 ) + AM_RANGE(0x0000, 0x7fff) AM_WRITE(MWA8_ROM) /* Fixed ROM */ + +// AM_RANGE(0x0000 , 0xbfff) AM_WRITE(MWA8_ROM) +// AM_RANGE(0xc000 , 0xdfff) AM_WRITE(MWA8_RAM) AM_MIRROR(0x2000) +ADDRESS_MAP_END + +static ADDRESS_MAP_START( sms_readport, ADDRESS_SPACE_IO, 8 ) + ADDRESS_MAP_FLAGS( AMEF_ABITS(8) ) +ADDRESS_MAP_END + +static ADDRESS_MAP_START( sms_writeport, ADDRESS_SPACE_IO, 8 ) + ADDRESS_MAP_FLAGS( AMEF_ABITS(8) ) +ADDRESS_MAP_END + +/* Precalculated tables for H/V counters. Note the position the counter 'jumps' is marked with with + an empty comment */ +static UINT8 hc_256[] = +{ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,/**/0x94, 0x95, 0x96, 0x97, 0x98, 0x99, + 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, + 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, + 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, + 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, + 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, + 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, + 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, +}; + + +static UINT8 vc_ntsc_192[] = +{ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,/**/0xd5, 0xd6, 0xd7, 0xd8, 0xd9, + 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, + 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, + 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, +}; + +static UINT8 vc_ntsc_224[] = +{ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,/**/0xe5, 0xe6, 0xe7, 0xe8, 0xe9, + 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, + 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, +}; + +static UINT8 vc_ntsc_240[] = +{ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 +}; + + + +static UINT8 vc_pal_192[] = +{ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, + 0xf0, 0xf1, 0xf2,/**/0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, + 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, + 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, + 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, + 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, +}; + + +static UINT8 vc_pal_224[] = +{ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, + 0x00, 0x01, 0x02,/**/0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, + 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, + 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, + 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, +}; + +static UINT8 vc_pal_240[] = +{ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,/**/0xd2, 0xd3, 0xd4, 0xd5, 0xd6, + 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, + 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, + 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, +}; + +static struct +{ + UINT8 sms2_name[40]; + int sms2_valid; + int sms2_height; + int sms2_tilemap_height; + UINT8* sms_vcounter_table; + UINT8* sms_hcounter_table; + +} sms_mode_table[] = +{ + /* NTSC Modes */ + { "Graphic 1 (NTSC)", 0, 192, 224, vc_ntsc_192, hc_256 }, + { "Text (NTSC)", 0, 192, 224, vc_ntsc_192, hc_256 }, + { "Graphic 2 (NTSC)", 0, 192, 224, vc_ntsc_192, hc_256 }, + { "Mode 1+2 (NTSC)" , 0, 192, 224, vc_ntsc_192, hc_256 }, + { "Multicolor (NTSC)", 0, 192, 224, vc_ntsc_192, hc_256 }, + { "Mode 1+3 (NTSC)", 0, 192, 224, vc_ntsc_192, hc_256 }, + { "Mode 2+3 (NTSC)", 0, 192, 224, vc_ntsc_192, hc_256 }, + { "Mode 1+2+3 (NTSC)", 0, 192, 224, vc_ntsc_192, hc_256 }, + { "Mode 4 (NTSC)", 1, 192, 224, vc_ntsc_192, hc_256 }, + { "Invalid Text (NTSC)", 0, 192, 224, vc_ntsc_192, hc_256 }, + { "Mode 4 (NTSC)", 1, 192, 224, vc_ntsc_192, hc_256 }, + { "Mode 4 (224-line) (NTSC)", 1, 224, 256, vc_ntsc_224, hc_256 }, + { "Mode 4 (NTSC)", 1, 192, 224, vc_ntsc_192, hc_256 }, + { "Invalid Text (NTSC)", 0, 192, 224, vc_ntsc_192, hc_256 }, + { "Mode 4 (240-line) (NTSC)", 1, 240, 256, vc_ntsc_240, hc_256 }, + { "Mode 4 (NTSC)", 1, 192, 244, vc_ntsc_192, hc_256 }, + + /* Pal Modes (different Vcounter) */ + { "Graphic 1 (PAL)", 0, 192, 224, vc_pal_192, hc_256 }, + { "Text (PAL)", 0, 192, 224, vc_pal_192, hc_256 }, + { "Graphic 2 (PAL)", 0, 192, 224, vc_pal_192, hc_256 }, + { "Mode 1+2 (PAL)" , 0, 192, 224, vc_pal_192, hc_256 }, + { "Multicolor (PAL)", 0, 192, 224, vc_pal_192, hc_256 }, + { "Mode 1+3 (PAL)", 0, 192, 224, vc_pal_192, hc_256 }, + { "Mode 2+3 (PAL)", 0, 192, 224, vc_pal_192, hc_256 }, + { "Mode 1+2+3 (PAL)", 0, 192, 224, vc_pal_192, hc_256 }, + { "Mode 4 (PAL)", 1, 192, 224, vc_pal_192, hc_256 }, + { "Invalid Text (PAL)", 0, 192, 224, vc_pal_192, hc_256 }, + { "Mode 4 (PAL)", 1, 192, 224, vc_pal_192, hc_256 }, + { "Mode 4 (224-line) (PAL)", 1, 224, 256, vc_pal_224, hc_256 }, + { "Mode 4 (PAL)", 1, 192, 224, vc_pal_192, hc_256 }, + { "Invalid Text (PAL)", 0, 192, 224, vc_pal_192, hc_256 }, + { "Mode 4 (240-line) (PAL)", 1, 240, 256, vc_pal_240, hc_256 }, + { "Mode 4 (PAL)", 1, 192, 244, vc_pal_192, hc_256 } +}; + +enum +{ + SMS_VDP = 0, // SMS1 VDP + SMS2_VDP = 1, // SMS2 VDP, or Game Gear VDP running in SMS2 Mode + GG_VDP = 2, // Game Gear VDP running in Game Gear Mode + GEN_VDP = 3 // Genesis VDP running in SMS2 Mode +}; + +static int sms_vdp_null_irq_callback(int status) +{ + return -1; +} + +static int sms_vdp_cpu0_irq_callback(int status) +{ + if (status==1) + { + cpunum_set_input_line(0,0,HOLD_LINE); + } + else + { + cpunum_set_input_line(0,0,CLEAR_LINE); + } + + return 0; +} + +static int sms_vdp_cpu1_irq_callback(int status) +{ + if (status==1) + { + cpunum_set_input_line(1,0,HOLD_LINE); + } + else + { + cpunum_set_input_line(1,0,CLEAR_LINE); + } + + return 0; +} + + +static int sms_vdp_cpu2_irq_callback(int status) +{ + if (status==1) + { + cpunum_set_input_line(2,0,HOLD_LINE); + } + else + { + cpunum_set_input_line(2,0,CLEAR_LINE); + } + + return 0; +} + + + + +struct sms_vdp +{ + UINT8 chip_id; + + UINT8 cmd_pend; + UINT8 cmd_part1; + UINT8 cmd_part2; + UINT16 addr_reg; + UINT8 cmd_reg; + UINT8 regs[0x10]; + UINT8 readbuf; + UINT8* vram; + UINT8* cram; + UINT8 writemode; + mame_bitmap* r_bitmap; + UINT8* tile_renderline; + UINT8* sprite_renderline; + + UINT8 sprite_collision; + UINT8 sprite_overflow; + + UINT8 yscroll; + UINT8 hint_counter; + + UINT8 frame_irq_pending; + UINT8 line_irq_pending; + + UINT8 vdp_type; + + UINT8 gg_cram_latch; // gamegear specific. + + /* below are MAME specific, to make things easier */ + UINT8 screen_mode; + UINT8 is_pal; + int sms_scanline_counter; + int sms_total_scanlines; + int sms_framerate; + emu_timer* sms_scanline_timer; + UINT16* cram_mamecolours; // for use on RGB_DIRECT screen + int (*set_irq)(int state); + +}; + + + +static void *start_vdp(running_machine *machine, int type) +{ + struct sms_vdp *chip; + + chip = auto_malloc(sizeof(*chip)); + memset(chip, 0, sizeof(*chip)); + + chip->vdp_type = type; + + chip->set_irq = sms_vdp_null_irq_callback; + + chip->cmd_pend = 0; + chip->cmd_part1 = 0; + chip->cmd_part2 = 0; + chip->addr_reg = 0; + chip->cmd_reg = 0; + + chip->regs[0x0] = 0x06; // mode 4 + chip->regs[0x1] = 0x18; // mode 4 + chip->regs[0x2] = 0; + chip->regs[0x3] = 0; + chip->regs[0x4] = 0; + chip->regs[0x5] = 0; + chip->regs[0x6] = 0; + chip->regs[0x7] = 0; + chip->regs[0x8] = 0; + chip->regs[0x9] = 0; + chip->regs[0xa] = 0; + /* b-f don't matter */ + chip->readbuf = 0; + chip->vram = auto_malloc(0x4000); + memset(chip->vram,0x00,0x4000); + + //printf("%d\n", (*chip->set_irq)(200)); + + if (chip->vdp_type==GG_VDP) + { + chip->cram = auto_malloc(0x0040); + memset(chip->cram,0x00,0x0040); + chip->cram_mamecolours = auto_malloc(0x0080); + memset(chip->cram_mamecolours,0x00,0x0080); + chip->gg_cram_latch = 0; + } + else + { + chip->cram = auto_malloc(0x0020); + memset(chip->cram,0x00,0x0020); + chip->cram_mamecolours = auto_malloc(0x0040); + memset(chip->cram_mamecolours,0x00,0x0040); + } + + chip->tile_renderline = auto_malloc(256+8); + memset(chip->tile_renderline,0x00,256+8); + + chip->sprite_renderline = auto_malloc(256+32); + memset(chip->sprite_renderline,0x00,256+32); + + chip->writemode = 0; + chip->r_bitmap = auto_bitmap_alloc(machine->screen[0].width,machine->screen[0].height,machine->screen[0].format); + + chip->sms_scanline_timer = timer_alloc_ptr(sms_scanline_timer_callback, chip); + + return chip; +} + +/* stop timer and clear ram.. used on megatech when we switch between genesis and sms mode */ +void segae_md_sms_stop_scanline_timer(void) +{ + timer_adjust_ptr(md_sms_vdp->sms_scanline_timer, attotime_never, attotime_never); + memset(md_sms_vdp->vram,0x00,0x4000); +} + + +#ifdef UNUSED_FUNCTION +static READ8_HANDLER( z80_unmapped_r ) +{ + printf("unmapped z80 read %04x\n",offset); + return 0; +} + +static WRITE8_HANDLER( z80_unmapped_w ) +{ + printf("unmapped z80 write %04x\n",offset); +} +#endif + +static UINT8 vcounter_r(struct sms_vdp *chip) +{ +// return vc_pal_224[sms_scanline_counter%(sizeof vc_pal_224)]; + UINT8 retvalue; + int scanline = chip->sms_scanline_counter%chip->sms_total_scanlines; + + retvalue = sms_mode_table[chip->screen_mode].sms_vcounter_table[scanline]; + + return retvalue; + //printf("retvalue %d\n"; +} + + +static UINT8 vdp_data_r(struct sms_vdp *chip) +{ + UINT8 retdata = chip->readbuf; + chip->readbuf = SMS_VDP_VRAM(chip->addr_reg); + chip->addr_reg++; chip->addr_reg&=0x3fff; + return retdata; +} + +static void vdp_data_w(UINT8 data, struct sms_vdp* chip) +{ + /* data writes clear the pending flag */ + chip->cmd_pend = 0; + + if (chip->writemode==0) + { /* Write to VRAM */ + SMS_VDP_VRAM(chip->addr_reg)=data; + chip->addr_reg++; chip->addr_reg&=0x3fff; + chip->readbuf = data; // quirk of the VDP + } + else if (chip->writemode==1) + { + if (chip->vdp_type==GG_VDP) + { + if (!(chip->addr_reg&1)) + { /* Even address, value latched */ + chip->gg_cram_latch = data; + } + else + { + chip->cram[(chip->addr_reg&0x3e)+1]=data; + chip->cram[(chip->addr_reg&0x3e)+0]=chip->gg_cram_latch; + + /* Set Colour */ + { + UINT16 palword; + UINT8 r,g,b; + + palword = ((chip->cram[(chip->addr_reg&0x3e)+1])<<8)|(chip->cram[(chip->addr_reg&0x3e)+0]); + + //printf("addr %04x palword %04x\n", chip->addr_reg&0x3f, palword); + + r = (palword & 0x000f)>>0; + g = (palword & 0x00f0)>>4; + b = (palword & 0x0f00)>>8; + palette_set_color_rgb(Machine,(chip->addr_reg&0x3e)/2, pal4bit(r), pal4bit(g), pal4bit(b)); + chip->cram_mamecolours[(chip->addr_reg&0x3e)/2]=(b<<1)|(g<<6)|(r<<11); + } + } + } + else + { + chip->cram[chip->addr_reg&0x1f]=data; + + /* Set Colour */ + { + UINT8 r,g,b; + r = (data & 0x03)>>0; + g = (data & 0x0c)>>2; + b = (data & 0x30)>>4; + palette_set_color_rgb(Machine,chip->addr_reg&0x1f, pal2bit(r), pal2bit(g), pal2bit(b)); + chip->cram_mamecolours[chip->addr_reg&0x1f]=(b<<3)|(g<<8)|(r<<13); + } + + } + + chip->addr_reg++; chip->addr_reg&=0x3fff; + chip->readbuf = data; // quirk of the VDP + + } + +} + +static UINT8 vdp_ctrl_r(struct sms_vdp *chip) +{ + UINT8 retvalue; + + retvalue = (chip->frame_irq_pending<<7) | + (chip->sprite_overflow<<6) | + (chip->sprite_collision<<5); + + chip->cmd_pend = 0; + chip->frame_irq_pending = 0; + chip->line_irq_pending = 0; + chip->sprite_collision = 0; + chip->sprite_overflow = 0; + + (chip->set_irq)(0); // clear IRQ; + + + return retvalue; +} + +/* check me */ +static void vdp_update_code_addr_regs(struct sms_vdp *chip) +{ + chip->addr_reg = ((chip->cmd_part2&0x3f)<<8) | chip->cmd_part1; + chip->cmd_reg = (chip->cmd_part2&0xc0)>>6; +} + +static void vdp_set_register(struct sms_vdp *chip) +{ + UINT8 reg = chip->cmd_part2&0x0f; + chip->regs[reg] = chip->cmd_part1; + + //if(reg==0) printf("setting reg 0 to %02x\n",chip->cmd_part1); + + //if (reg>0xa) printf("Invalid register write to register %01x\n",reg); + + if(reg==1) + { + if ((chip->regs[0x1]&0x20) && chip->frame_irq_pending) + { + (chip->set_irq)(1); // set IRQ; + } + else + { + (chip->set_irq)(0); // clear IRQ; + } + } + + if(reg==0) + { + if ((chip->regs[0x0]&0x10) && chip->line_irq_pending) + { + (chip->set_irq)(1); // set IRQ; + } + else + { + (chip->set_irq)(0); // clear IRQ; + } + } + + +// printf("VDP: setting register %01x to %02x\n",reg, chip->cmd_part1); +} + +static void vdp_ctrl_w(UINT8 data, struct sms_vdp *chip) +{ + if (chip->cmd_pend) + { /* Part 2 of a command word write */ + chip->cmd_pend = 0; + chip->cmd_part2 = data; + vdp_update_code_addr_regs(chip); + + switch (chip->cmd_reg) + { + case 0x0: /* VRAM read mode */ + chip->readbuf = SMS_VDP_VRAM(chip->addr_reg); + chip->addr_reg++; chip->addr_reg&=0x3fff; + chip->writemode = 0; + break; + + case 0x1: /* VRAM write mode */ + chip->writemode = 0; + break; + + case 0x2: /* REG setting */ + vdp_set_register(chip); + chip->writemode = 0; + break; + + case 0x3: /* CRAM write mode */ + chip->writemode = 1; + break; + } + } + else + { /* Part 1 of a command word write */ + chip->cmd_pend = 1; + chip->cmd_part1 = data; + vdp_update_code_addr_regs(chip); + } +} + +/* for the Genesis */ + +READ8_HANDLER( md_sms_vdp_vcounter_r ) +{ + return vcounter_r(md_sms_vdp); +} + +READ8_HANDLER( md_sms_vdp_data_r ) +{ + return vdp_data_r(md_sms_vdp); +} + +WRITE8_HANDLER( md_sms_vdp_data_w ) +{ + vdp_data_w(data, md_sms_vdp); +} + +READ8_HANDLER( md_sms_vdp_ctrl_r ) +{ + return vdp_ctrl_r(md_sms_vdp); +} + +WRITE8_HANDLER( md_sms_vdp_ctrl_w ) +{ + vdp_ctrl_w(data, md_sms_vdp); +} + + +/* Read / Write Handlers - call other functions */ + +READ8_HANDLER( sms_vcounter_r ) +{ + return vcounter_r(vdp1); +} + +READ8_HANDLER( sms_vdp_data_r ) +{ + return vdp_data_r(vdp1); +} + +WRITE8_HANDLER( sms_vdp_data_w ) +{ + vdp_data_w(data, vdp1); +} + +READ8_HANDLER( sms_vdp_ctrl_r ) +{ + return vdp_ctrl_r(vdp1); +} + +WRITE8_HANDLER( sms_vdp_ctrl_w ) +{ + vdp_ctrl_w(data, vdp1); +} + +WRITE8_HANDLER( sms_sn76496_w ) +{ + SN76496_0_w(0, data & 0xff); +} + +static void draw_tile_line(int drawxpos, int tileline, UINT16 tiledata, UINT8* linebuf, struct sms_vdp* chip) +{ + int xx; + UINT32 gfxdata; + UINT16 gfx_base = (tiledata & 0x01ff)<<5; + UINT8 flipx = (tiledata & 0x0200)>>9; + UINT8 flipy = (tiledata & 0x0400)>>10; + UINT8 pal = (tiledata & 0x0800)>>11; + UINT8 pri = (tiledata & 0x1000)>>12; + + if (flipy) + { + gfx_base+=(7-tileline)*4; + } + else + { + gfx_base+=tileline*4; + } + + gfxdata = (SMS_VDP_VRAM(gfx_base)<<24)|(SMS_VDP_VRAM(gfx_base+1)<<16)|(SMS_VDP_VRAM(gfx_base+2)<<8)|(SMS_VDP_VRAM(gfx_base+3)<<0); + + for (xx=0;xx<8;xx++) + { + UINT8 pixel; + + if (flipx) + { + pixel = (( (gfxdata>>(0+xx) ) &0x00000001)<<3)| + (( (gfxdata>>(8+xx) ) &0x00000001)<<2)| + (( (gfxdata>>(16+xx) ) &0x00000001)<<1)| + (( (gfxdata>>(24+xx) ) &0x00000001)<<0); + } + else + { + pixel = (( (gfxdata>>(7-xx) ) &0x00000001)<<3)| + (( (gfxdata>>(15-xx) ) &0x00000001)<<2)| + (( (gfxdata>>(23-xx) ) &0x00000001)<<1)| + (( (gfxdata>>(31-xx) ) &0x00000001)<<0); + } + + pixel += pal*0x10; + + if (!pri) linebuf[drawxpos+xx] = pixel; + else + { + if (pixel&0xf) + linebuf[drawxpos+xx] = pixel|0x80; + else + linebuf[drawxpos+xx] = pixel; + + } + } +} + +static void sms_render_spriteline(int scanline, struct sms_vdp* chip) +{ + int spritenum; + int height = 8; + int width = 8; + int max_sprites = 8; + int visible_line = 0; + + UINT16 table_base = (chip->regs[0x5]&0x7e) << 7; + UINT8 pattern_bit = (chip->regs[0x6]&0x04) >> 2; // high bit of the tile # (because spriteram can only contain an 8-bit tile #) + + + memset(chip->sprite_renderline, 0, 256+32); + + for (spritenum = 0;spritenum<64;spritenum++) + { + int xpos,ypos,num; + /* + 00: yyyyyyyyyyyyyyyy + 10: yyyyyyyyyyyyyyyy + 20: yyyyyyyyyyyyyyyy + 30: yyyyyyyyyyyyyyyy + 40: ???????????????? + 50: ???????????????? + 60: ???????????????? + 70: ???????????????? + 80: xnxnxnxnxnxnxnxn + 90: xnxnxnxnxnxnxnxn + A0: xnxnxnxnxnxnxnxn + B0: xnxnxnxnxnxnxnxn + C0: xnxnxnxnxnxnxnxn + D0: xnxnxnxnxnxnxnxn + E0: xnxnxnxnxnxnxnxn + F0: xnxnxnxnxnxnxnxn + */ + + ypos = SMS_VDP_VRAM(table_base+spritenum); + xpos = SMS_VDP_VRAM(table_base+0x80+spritenum*2+0); + num = SMS_VDP_VRAM(table_base+0x80+spritenum*2+1)|(pattern_bit<<8); + + if (chip->regs[0x1]&0x2) + { + num &=0x1fe; + height=16; + } + else height = 8; + + + xpos+=16; // allow room either side for clipping (avoids xdrawpos of -8 if bit below is set) + + if (chip->regs[0x0]&0x08) xpos-=8; + + if ((sms_mode_table[chip->screen_mode].sms2_height)==192) + { + if (ypos == 0xd0) + return; + } + + ypos++; + + num <<= 5; + //num+=((scanline-ypos)&0x7)*4; + + visible_line = 0; + + if (ypos<=scanline && ypos+height>scanline) + { + visible_line = 1; + num+=((scanline-ypos)&(height-1))*4; + + } + else if (ypos+height>0x100) + { + if (scanline< ypos+height-0x100) + { + visible_line = 1; + num+=((scanline-ypos)&(height-1))*4; + + } + } + + if (visible_line) + { + int xx; + UINT32 gfxdata; + + gfxdata = (SMS_VDP_VRAM(num&0x3fff)<<24)|(SMS_VDP_VRAM((num+1)&0x3fff)<<16)|(SMS_VDP_VRAM((num+2)&0x3fff)<<8)|(SMS_VDP_VRAM((num+3)&0x3fff)<<0); + + + for (xx=0;xx<8;xx++) + { + UINT8 pixel = (( (gfxdata>>(0+xx) ) &0x00000001)<<3)| + (( (gfxdata>>(8+xx) ) &0x00000001)<<2)| + (( (gfxdata>>(16+xx) ) &0x00000001)<<1)| + (( (gfxdata>>(24+xx) ) &0x00000001)<<0); + + if (pixel) + { + if (!chip->sprite_renderline[xpos+((width-1)-xx)]) + { + chip->sprite_renderline[xpos+((width-1)-xx)] = pixel; + } + else + { + chip->sprite_collision = 1; + } + } + } + + max_sprites--; + + if (max_sprites==0) + { + chip->sprite_overflow = 1; + return; + } + + } + } +} + +static void sms_render_tileline(int scanline, struct sms_vdp* chip) +{ + int column = 0; + int count = 32; + int drawxpos; + + UINT8 xscroll = chip->regs[0x8]; + UINT8 yscroll = chip->yscroll; + UINT16 table_base = (chip->regs[0x2]&0x0e)<<10; + UINT16 our_base; + UINT8 our_line = (scanline+yscroll) & 0x7; + + /* In 224 and 240 line modes the table base is different */ + if ((sms_mode_table[chip->screen_mode].sms2_height)!=192) + { + table_base &=0x3700; table_base|=0x700; + } + + if ((chip->regs[0x0]&0x40) && scanline < 16) + { + xscroll = 0; + } + +// xscroll = 0; + +// table_base -= 0x0100; + + our_base = table_base+(((scanline+yscroll)%sms_mode_table[chip->screen_mode].sms2_tilemap_height)>>3)*64;// + (yscroll>>3)*32; + + our_base &=0x3fff; + + memset(chip->tile_renderline, (chip->regs[0x7]&0x0f)+0x10, 256+8); + + drawxpos = xscroll&0x7; + column = 32-(xscroll>>3); + + do + { + UINT16 tiledata = (SMS_VDP_VRAM((our_base+(column&0x1f)*2+1)&0x3fff) << 8) | + (SMS_VDP_VRAM((our_base+(column&0x1f)*2+0)&0x3fff) << 0); + +// UINT16 pattern = ((column+((scanline>>3)*32)) & 0x01ff)<<5; + + draw_tile_line(drawxpos, our_line, tiledata, chip->tile_renderline, chip); + + drawxpos+=8; + column++; + column&=0x1f; + count--; + } while (count); + +} + +static void sms_copy_to_renderbuffer(int scanline, struct sms_vdp* chip) +{ + int x; + UINT16* lineptr = BITMAP_ADDR16(chip->r_bitmap, scanline, 0); + + for (x=0;x<256;x++) + { + UINT8 dat = chip->tile_renderline[x]; + UINT8 col; + + + col = (chip->regs[0x7]&0x0f)+0x10; + lineptr[x] = chip->cram_mamecolours[col]; + + + if ((x<8 && (chip->regs[0x0]&0x20)) || !(chip->regs[0x1]&0x40)) + continue; + + + if (!(dat & 0x80)) + { + lineptr[x] = chip->cram_mamecolours[dat&0x1f]; + if ((dat&0xf)==0x0) lineptr[x]|=0x8000; + + } + + if (chip->sprite_renderline[x+16]) + { + lineptr[x] = chip->cram_mamecolours[chip->sprite_renderline[x+16]+0x10]; + } + + if (dat & 0x80) + { + lineptr[x] = chip->cram_mamecolours[dat&0x1f]; + if ((dat&0xf)==0x0) lineptr[x]|=0x8000; + } + + } + +} + +static void sms_draw_scanline(int scanline, struct sms_vdp* chip) +{ + + if (scanline>=0 && scanline<sms_mode_table[chip->screen_mode].sms2_height) + { + sms_render_spriteline(scanline, chip); + sms_render_tileline(scanline, chip); + sms_copy_to_renderbuffer(scanline, chip); + + } +} + + +static TIMER_CALLBACK_PTR( sms_scanline_timer_callback ) +{ + /* This function is called at the very start of every scanline starting at the very + top-left of the screen. The first scanline is scanline 0 (we set scanline to -1 in + VIDEO_EOF) */ + + /* Compensate for some rounding errors + + When the counter reaches 314 (or whatever the max lines is) we should have reached the + end of the frame, however due to rounding errors in the timer calculation we're not quite + there. Let's assume we are still in the previous scanline for now. + + The position to get the H position also has to compensate for a few errors + */ +// printf("num %d\n",num ); + struct sms_vdp *chip = param; + + if (chip->sms_scanline_counter<(chip->sms_total_scanlines-1)) + { + chip->sms_scanline_counter++; + timer_adjust_ptr(chip->sms_scanline_timer, ATTOTIME_IN_HZ(chip->sms_framerate * chip->sms_total_scanlines), attotime_zero); + + if (chip->sms_scanline_counter>sms_mode_table[chip->screen_mode].sms2_height) + { + chip->hint_counter=chip->regs[0xa]; + } + + if (chip->sms_scanline_counter==0) + { + chip->hint_counter=chip->regs[0xa]; + } + + if (chip->sms_scanline_counter<=192) + { + chip->hint_counter--; + + if (chip->hint_counter==0xff) + { + //if (chip->chip_id==2) printf("irq triggerd on scanline %d %d\n", vdp1->sms_scanline_counter, vdp2->sms_scanline_counter); + + chip->line_irq_pending = 1; + chip->hint_counter=chip->regs[0xa]; + if (chip->regs[0x0]&0x10) + { + (chip->set_irq)(1); // set IRQ; + } + else + { + (chip->set_irq)(0); // clear IRQ; + } + } + + } + + + sms_draw_scanline(chip->sms_scanline_counter, chip); + + //if(sms_scanline_counter==0) chip->sprite_collision = 0; + + if (chip->sms_scanline_counter==sms_mode_table[chip->screen_mode].sms2_height+1 ) + { + chip->frame_irq_pending = 1; + if (chip->regs[0x1]&0x20) + { + (chip->set_irq)(1); // set IRQ; + } + else + { + (chip->set_irq)(0); // clear IRQ; + } + } + } + else + { /* if we're called passed the total number of scanlines then assume we're still on the last one. + this can happen due to rounding errors */ + chip->sms_scanline_counter = chip->sms_total_scanlines-1; + } +} + +#ifdef UNUSED_FUNCTION +static void show_tiles(struct sms_vdp* chip) +{ + int x,y,xx,yy; + UINT16 count = 0; + + for (y=0;y<16;y++) + { + for (x=0;x<32;x++) + { + for (yy=0;yy<8;yy++) + { + int drawypos = y*8+yy; + UINT16* lineptr = BITMAP_ADDR16(chip->r_bitmap, drawypos, 0); + + UINT32 gfxdata = (SMS_VDP_VRAM(count)<<24)|(SMS_VDP_VRAM(count+1)<<16)|(SMS_VDP_VRAM(count+2)<<8)|(SMS_VDP_VRAM(count+3)<<0); + + for (xx=0;xx<8;xx++) + { + int drawxpos = x*8+xx; + + UINT8 pixel = (( (gfxdata>>(0+xx) ) &0x00000001)<<3)| + (( (gfxdata>>(8+xx) ) &0x00000001)<<2)| + (( (gfxdata>>(16+xx) ) &0x00000001)<<1)| + (( (gfxdata>>(24+xx) ) &0x00000001)<<0); + + lineptr[drawxpos] = chip->cram_mamecolours[pixel+16]; + + } + + + count+=4;count&=0x3fff; + } + } + } +} +#endif + +/* + Register $00 - Mode Control No. 1 + + D7 - 1= Disable vertical scrolling for columns 24-31 + D6 - 1= Disable horizontal scrolling for rows 0-1 + D5 - 1= Mask column 0 with overscan color from register #7 + D4 - (IE1) 1= Line interrupt enable + D3 - (EC) 1= Shift sprites left by 8 pixels + D2 - (M4) 1= Use Mode 4, 0= Use TMS9918 modes (selected with M1, M2, M3) + D1 - (M2) Must be 1 for M1/M3 to change screen height in Mode 4. + Otherwise has no effect. + D0 - 1= No sync, display is monochrome, 0= Normal display + + Bits 0 and 5 have no effect on the GameGear in either mode, while bit 6 + has no effect in GG mode but works normally in SMS mode. + */ + + /* + Register $01 - Mode Control No. 2 + + D7 - No effect + D6 - (BLK) 1= Display visible, 0= display blanked. + D5 - (IE0) 1= Frame interrupt enable. + D4 - (M1) Selects 224-line screen for Mode 4 if M2=1, else has no effect. + D3 - (M3) Selects 240-line screen for Mode 4 if M2=1, else has no effect. + D2 - No effect + D1 - Sprites are 1=16x16,0=8x8 (TMS9918), Sprites are 1=8x16,0=8x8 (Mode 4) + D0 - Sprite pixels are doubled in size. + + Even though some games set bit 7, it does nothing. + */ + +static void end_of_frame(struct sms_vdp *chip) +{ + UINT8 m1 = (chip->regs[0x1]&0x10)>>4; + UINT8 m2 = (chip->regs[0x0]&0x02)>>1; + UINT8 m3 = (chip->regs[0x1]&0x08)>>3; + UINT8 m4 = (chip->regs[0x0]&0x04)>>2; + UINT8 m5 = chip->is_pal; + chip->screen_mode = m1|(m2<<1)|(m3<<2)|(m4<<3)|(m5<<4); + + if (chip->vdp_type!=GG_VDP) /* In GG mode the Game Gear resolution is fixed */ + { + rectangle visarea; + + visarea.min_x = 0; + visarea.max_x = 256-1; + visarea.min_y = 0; + visarea.max_y = sms_mode_table[chip->screen_mode].sms2_height-1; + + if (chip->chip_id==3) video_screen_configure(0, 256, 256, &visarea, HZ_TO_ATTOSECONDS(chip->sms_framerate)); + + } + else /* 160x144 */ + { + rectangle visarea; + visarea.min_x = (256-160)/2; + visarea.max_x = (256-160)/2+160-1; + visarea.min_y = (192-144)/2; + visarea.max_y = (192-144)/2+144-1; + } + + + +// printf("Mode: %s is ok\n", sms_mode_table[chip->screen_mode].sms2_name); + + chip->sms_scanline_counter = -1; + chip->yscroll = chip->regs[0x9]; // this can't change mid-frame + timer_adjust_ptr(chip->sms_scanline_timer, attotime_zero, attotime_zero); +} + +#ifdef UNUSED_FUNCTION +VIDEO_EOF(sms) +{ + end_of_frame(vdp1); + //if (SMS_PAUSE_BUTTON) cpunum_set_input_line(0,INPUT_LINE_NMI,PULSE_LINE); // not on systeme!!! +} +#endif + +static VIDEO_START(sms) +{ + +// vdp->is_pal = 1; +// vdp->sms_total_scanlines = 313; +// vdp->sms_framerate = 50; +} + +#ifdef UNUSED_FUNCTION +MACHINE_RESET(sms) +{ + timer_adjust_ptr(vdp1->sms_scanline_timer, attotime_zero, attotime_zero); +} +#endif + +/* Sega System E */ + +/******************************************************************************* + Input Ports +******************************************************************************** + mostly unknown for the time being +*******************************************************************************/ + + /* The Coinage is similar to Sega System 1 and C2, but + it seems that Free Play is not used in all games + (in fact, the only playable game that use it is + Riddle of Pythagoras) */ + +#define SEGA_COIN_A \ + PORT_DIPNAME( 0x0f, 0x0f, DEF_STR( Coin_A ) ) PORT_DIPLOCATION("SW1:1,2,3,4") \ + PORT_DIPSETTING( 0x07, DEF_STR( 4C_1C ) ) \ + PORT_DIPSETTING( 0x08, DEF_STR( 3C_1C ) ) \ + PORT_DIPSETTING( 0x09, DEF_STR( 2C_1C ) ) \ + PORT_DIPSETTING( 0x05, "2 Coins/1 Credit 5/3 6/4" ) \ + PORT_DIPSETTING( 0x04, "2 Coins/1 Credit, 4/3" ) \ + PORT_DIPSETTING( 0x0f, DEF_STR( 1C_1C ) ) \ + PORT_DIPSETTING( 0x03, "1 Coin/1 Credit, 5/6" ) \ + PORT_DIPSETTING( 0x02, "1 Coin/1 Credit, 4/5" ) \ + PORT_DIPSETTING( 0x01, "1 Coin/1 Credit, 2/3" ) \ + PORT_DIPSETTING( 0x06, DEF_STR( 2C_3C ) ) \ + PORT_DIPSETTING( 0x0e, DEF_STR( 1C_2C ) ) \ + PORT_DIPSETTING( 0x0d, DEF_STR( 1C_3C ) ) \ + PORT_DIPSETTING( 0x0c, DEF_STR( 1C_4C ) ) \ + PORT_DIPSETTING( 0x0b, DEF_STR( 1C_5C ) ) \ + PORT_DIPSETTING( 0x0a, DEF_STR( 1C_6C ) ) + +#define SEGA_COIN_B \ + PORT_DIPNAME( 0xf0, 0xf0, DEF_STR( Coin_B ) ) PORT_DIPLOCATION("SW1:5,6,7,8") \ + PORT_DIPSETTING( 0x70, DEF_STR( 4C_1C ) ) \ + PORT_DIPSETTING( 0x80, DEF_STR( 3C_1C ) ) \ + PORT_DIPSETTING( 0x90, DEF_STR( 2C_1C ) ) \ + PORT_DIPSETTING( 0x50, "2 Coins/1 Credit 5/3 6/4" ) \ + PORT_DIPSETTING( 0x40, "2 Coins/1 Credit, 4/3" ) \ + PORT_DIPSETTING( 0xf0, DEF_STR( 1C_1C ) ) \ + PORT_DIPSETTING( 0x30, "1 Coin/1 Credit, 5/6" ) \ + PORT_DIPSETTING( 0x20, "1 Coin/1 Credit, 4/5" ) \ + PORT_DIPSETTING( 0x10, "1 Coin/1 Credit, 2/3" ) \ + PORT_DIPSETTING( 0x60, DEF_STR( 2C_3C ) ) \ + PORT_DIPSETTING( 0xe0, DEF_STR( 1C_2C ) ) \ + PORT_DIPSETTING( 0xd0, DEF_STR( 1C_3C ) ) \ + PORT_DIPSETTING( 0xc0, DEF_STR( 1C_4C ) ) \ + PORT_DIPSETTING( 0xb0, DEF_STR( 1C_5C ) ) \ + PORT_DIPSETTING( 0xa0, DEF_STR( 1C_6C ) ) + + +static INPUT_PORTS_START( transfrm ) /* Used By Transformer */ + PORT_START_TAG("DSW0") /* Read from Port 0xf2 */ + SEGA_COIN_A + SEGA_COIN_B + + PORT_START_TAG("DSW1") /* Read from Port 0xf3 */ + PORT_DIPNAME( 0x01, 0x00, "1 Player Only" ) PORT_DIPLOCATION("SW2:1") + PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x01, DEF_STR( On ) ) + PORT_DIPNAME( 0x02, 0x00, DEF_STR( Demo_Sounds ) ) PORT_DIPLOCATION("SW2:2") + PORT_DIPSETTING( 0x02, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x00, DEF_STR( On ) ) + PORT_DIPNAME( 0x0c, 0x0c, DEF_STR( Lives ) ) PORT_DIPLOCATION("SW2:3,4") + PORT_DIPSETTING( 0x0c, "3" ) + PORT_DIPSETTING( 0x08, "4" ) + PORT_DIPSETTING( 0x04, "5" ) + PORT_DIPSETTING( 0x00, "Infinite (Cheat)") + PORT_DIPNAME( 0x30, 0x30, DEF_STR( Bonus_Life ) ) PORT_DIPLOCATION("SW2:5,6") + PORT_DIPSETTING( 0x20, "10k, 30k, 50k and 70k" ) + PORT_DIPSETTING( 0x30, "20k, 60k, 100k and 140k" ) + PORT_DIPSETTING( 0x10, "30k, 80k, 130k and 180k" ) + PORT_DIPSETTING( 0x00, "50k, 150k and 250k" ) + PORT_DIPNAME( 0xc0, 0xc0, DEF_STR( Difficulty ) ) PORT_DIPLOCATION("SW2:7,8") + PORT_DIPSETTING( 0x40, DEF_STR( Easy ) ) + PORT_DIPSETTING( 0xc0, DEF_STR( Medium ) ) + PORT_DIPSETTING( 0x80, DEF_STR( Hard ) ) + PORT_DIPSETTING( 0x00, DEF_STR( Hardest ) ) + + PORT_START_TAG("IN0") /* Read from Port 0xe0 */ + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN1 ) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_COIN2 ) + PORT_SERVICE_NO_TOGGLE(0x04, IP_ACTIVE_LOW) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_SERVICE1 ) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_START1 ) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_START2 ) + + PORT_START_TAG("IN1") /* Read from Port 0xe1 */ + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 ) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) +INPUT_PORTS_END + +static INPUT_PORTS_START( fantzn2 ) /* Used By Fantasy Zone 2 */ + PORT_START_TAG("DSW0") /* Read from Port 0xf2 */ + SEGA_COIN_A + SEGA_COIN_B + + PORT_START_TAG("DSW1") /* Read from Port 0xf3 */ + PORT_DIPUNUSED_DIPLOC( 0x01, 0x01, "SW2:1" ) + PORT_DIPNAME( 0x02, 0x00, DEF_STR( Demo_Sounds ) ) PORT_DIPLOCATION("SW2:2") + PORT_DIPSETTING( 0x02, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x00, DEF_STR( On ) ) + PORT_DIPNAME( 0x0c, 0x0c, DEF_STR( Lives ) ) PORT_DIPLOCATION("SW2:3,4") + PORT_DIPSETTING( 0x00, "2" ) + PORT_DIPSETTING( 0x0c, "3" ) + PORT_DIPSETTING( 0x08, "4" ) + PORT_DIPSETTING( 0x04, "5" ) + PORT_DIPNAME( 0x30, 0x30, "Timer" ) PORT_DIPLOCATION("SW2:5,6") + PORT_DIPSETTING( 0x20, "90" ) /* 210 seconds */ + PORT_DIPSETTING( 0x30, "80" ) /* 180 seconds */ + PORT_DIPSETTING( 0x10, "70" ) /* 150 seconds */ + PORT_DIPSETTING( 0x00, "60" ) /* 120 seconds */ + PORT_DIPNAME( 0xc0, 0xc0, DEF_STR( Difficulty ) ) PORT_DIPLOCATION("SW2:7,8") + PORT_DIPSETTING( 0x80, DEF_STR( Easy ) ) + PORT_DIPSETTING( 0xc0, DEF_STR( Normal ) ) + PORT_DIPSETTING( 0x40, DEF_STR( Hard ) ) + PORT_DIPSETTING( 0x00, DEF_STR( Hardest ) ) + + PORT_START_TAG("IN0") /* Read from Port 0xe0 */ + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN1 ) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_COIN2 ) + PORT_SERVICE_NO_TOGGLE(0x04, IP_ACTIVE_LOW) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_SERVICE1 ) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_START1 ) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_START2 ) + + PORT_START_TAG("IN1") /* Read from Port 0xe1 */ + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 ) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) +INPUT_PORTS_END + +static INPUT_PORTS_START( opaopa ) /* Used By Opa Opa */ + PORT_START_TAG("DSW0") /* Read from Port 0xf2 */ + SEGA_COIN_A + SEGA_COIN_B + + PORT_START_TAG("DSW1") /* Read from Port 0xf3 */ + PORT_DIPNAME( 0x01, 0x01, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW2:1") + PORT_DIPSETTING( 0x01, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x00, DEF_STR( On ) ) + PORT_DIPNAME( 0x02, 0x00, DEF_STR( Demo_Sounds ) ) PORT_DIPLOCATION("SW2:2") + PORT_DIPSETTING( 0x02, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x00, DEF_STR( On ) ) + PORT_DIPNAME( 0x0c, 0x0c, DEF_STR( Lives ) ) PORT_DIPLOCATION("SW2:3,4") + PORT_DIPSETTING( 0x00, "2" ) + PORT_DIPSETTING( 0x0c, "3" ) + PORT_DIPSETTING( 0x08, "4" ) + PORT_DIPSETTING( 0x04, "5" ) + PORT_DIPNAME( 0x30, 0x30, DEF_STR( Bonus_Life ) ) PORT_DIPLOCATION("SW2:5,6") + PORT_DIPSETTING( 0x30, "0x30 Unknown" ) + PORT_DIPSETTING( 0x20, "0x20 Unknown" ) + PORT_DIPSETTING( 0x10, "0x10 Unknown" ) + PORT_DIPSETTING( 0x00, "0x00 Unknown" ) + PORT_DIPNAME( 0xc0, 0xc0, DEF_STR( Difficulty ) ) PORT_DIPLOCATION("SW2:7,8") + PORT_DIPSETTING( 0x80, DEF_STR( Easy ) ) + PORT_DIPSETTING( 0xc0, DEF_STR( Normal ) ) + PORT_DIPSETTING( 0x40, DEF_STR( Hard ) ) + PORT_DIPSETTING( 0x00, DEF_STR( Hardest ) ) + + PORT_START_TAG("IN0") /* Read from Port 0xe0 */ + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN1 ) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_COIN2 ) + PORT_SERVICE_NO_TOGGLE(0x04, IP_ACTIVE_LOW) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_SERVICE1 ) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_START1 ) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_START2 ) + + PORT_START_TAG("IN1") /* Read from Port 0xe1 */ + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(1) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(1) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(1) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(1) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) + + PORT_START_TAG("IN2") /* Read from Port 0xe2 */ + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(2) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(2) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(2) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(2) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) +INPUT_PORTS_END + + +static INPUT_PORTS_START( tetrisse ) /* Used By Tetris */ + PORT_START_TAG("DSW0") /* Read from Port 0xf2 */ + SEGA_COIN_A + SEGA_COIN_B + + PORT_START_TAG("DSW1") /* Read from Port 0xf3 */ + PORT_DIPUNUSED_DIPLOC( 0x01, 0x01, "SW2:1" ) + PORT_DIPNAME( 0x02, 0x00, DEF_STR( Demo_Sounds ) ) PORT_DIPLOCATION("SW2:2") + PORT_DIPSETTING( 0x02, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x00, DEF_STR( On ) ) + PORT_DIPUNUSED_DIPLOC( 0x40, 0x40, "SW2:3" ) + PORT_DIPUNUSED_DIPLOC( 0x80, 0x80, "SW2:4" ) + PORT_DIPNAME( 0x30, 0x30, DEF_STR( Difficulty ) ) PORT_DIPLOCATION("SW2:5,6") + PORT_DIPSETTING( 0x20, DEF_STR( Easy ) ) + PORT_DIPSETTING( 0x30, DEF_STR( Normal ) ) + PORT_DIPSETTING( 0x10, DEF_STR( Hard ) ) + PORT_DIPSETTING( 0x00, DEF_STR( Hardest ) ) + PORT_DIPUNUSED_DIPLOC( 0x40, 0x40, "SW2:7" ) + PORT_DIPUNUSED_DIPLOC( 0x80, 0x80, "SW2:8" ) + + PORT_START_TAG("IN0") /* Read from Port 0xe0 */ + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN1 ) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_COIN2 ) + PORT_SERVICE_NO_TOGGLE(0x04, IP_ACTIVE_LOW) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_SERVICE1 ) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_START1 ) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_START2 ) + + PORT_START_TAG("IN1") /* Read from Port 0xe1 */ + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 ) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) +INPUT_PORTS_END + + +static INPUT_PORTS_START( hangonjr ) /* Used By Hang On Jr */ + PORT_START_TAG("DSW0") /* Read from Port 0xf2 */ + SEGA_COIN_A + SEGA_COIN_B + + PORT_START_TAG("DSW1") /* Read from Port 0xf3 */ + PORT_DIPNAME( 0x01, 0x01, DEF_STR( Unknown ) ) PORT_DIPLOCATION("SW2:1") /* Supose to be demo sound but has no effect */ + PORT_DIPSETTING( 0x01, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x00, DEF_STR( On ) ) + PORT_DIPNAME( 0x06, 0x06, "Enemies" ) PORT_DIPLOCATION("SW2:2,3") + PORT_DIPSETTING( 0x06, DEF_STR( Easy ) ) + PORT_DIPSETTING( 0x04, DEF_STR( Medium ) ) + PORT_DIPSETTING( 0x02, DEF_STR( Hard ) ) + PORT_DIPSETTING( 0x00, DEF_STR( Hardest ) ) + PORT_DIPNAME( 0x18, 0x18, DEF_STR( Difficulty ) ) PORT_DIPLOCATION("SW2:4,5") + PORT_DIPSETTING( 0x18, DEF_STR( Easy ) ) + PORT_DIPSETTING( 0x10, DEF_STR( Medium ) ) + PORT_DIPSETTING( 0x08, DEF_STR( Hard ) ) + PORT_DIPSETTING( 0x00, DEF_STR( Hardest ) ) + PORT_DIPUNUSED_DIPLOC( 0x20, 0x20, "SW2:6" ) /* These three dips seems to be unused */ + PORT_DIPUNUSED_DIPLOC( 0x40, 0x40, "SW2:7" ) + PORT_DIPUNUSED_DIPLOC( 0x80, 0x80, "SW2:8" ) + + PORT_START_TAG("IN0") /* Read from Port 0xe0 */ + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN1 ) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_COIN2 ) + PORT_SERVICE_NO_TOGGLE(0x04, IP_ACTIVE_LOW) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_SERVICE1 ) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_START1 ) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) + + PORT_START_TAG("IN1") /* Read from Port 0xe1 */ + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) + + PORT_START_TAG("IN2") /* Read from Port 0xf8 */ + PORT_BIT( 0xff, 0x80, IPT_PADDLE ) PORT_MINMAX(0x20,0xe0) PORT_SENSITIVITY(100) PORT_KEYDELTA(4) + + PORT_START_TAG("IN3") /* Read from Port 0xf8 */ + PORT_BIT( 0xff, 0x00, IPT_PEDAL ) PORT_MINMAX(0x00,0xff) PORT_SENSITIVITY(100) PORT_KEYDELTA(20) +INPUT_PORTS_END + +static INPUT_PORTS_START( ridleofp ) /* Used By Riddle Of Pythagoras */ + PORT_START_TAG("DSW0") /* Read from Port 0xf2 */ + SEGA_COIN_A + PORT_DIPSETTING( 0x00, DEF_STR( Free_Play ) ) + SEGA_COIN_B + PORT_DIPSETTING( 0x00, DEF_STR( Free_Play ) ) + + PORT_START_TAG("DSW1") /* Read from Port 0xf3 */ + PORT_DIPNAME( 0x03, 0x02, DEF_STR( Lives ) ) PORT_DIPLOCATION("SW2:1,2") + PORT_DIPSETTING( 0x03, "3" ) + PORT_DIPSETTING( 0x02, "4" ) + PORT_DIPSETTING( 0x01, "5" ) + PORT_DIPSETTING( 0x00, "100 (Cheat)") + PORT_DIPUNUSED_DIPLOC( 0x04, 0x04, "SW2:3" ) + PORT_DIPNAME( 0x08, 0x08, "Ball Speed" ) PORT_DIPLOCATION("SW2:4") + PORT_DIPSETTING( 0x08, DEF_STR( Easy ) ) + PORT_DIPSETTING( 0x00, DEF_STR( Hard ) ) // difficult (on datasheet) + PORT_DIPUNUSED_DIPLOC( 0x10, 0x10, "SW2:5" ) + PORT_DIPNAME( 0x60, 0x60, DEF_STR( Bonus_Life ) ) PORT_DIPLOCATION("SW2:6,7") /* Values came from an original dipsheet */ + PORT_DIPSETTING( 0x60, "50K 100K 200K 1M 2M 10M 20M 50M" ) + PORT_DIPSETTING( 0x40, "100K 200K 1M 2M 10M 20M 50M" ) + PORT_DIPSETTING( 0x20, "200K 1M 2M 10M 20M 50M" ) + PORT_DIPSETTING( 0x00, DEF_STR( None ) ) + PORT_DIPUNUSED_DIPLOC( 0x80, 0x80, "SW2:8" ) + + PORT_START_TAG("IN0") /* Read from Port 0xe0 */ + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN1 ) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_COIN2 ) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_SERVICE1 ) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_START1 ) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) // Would Be IPT_START2 but the code doesn't use it + + PORT_START_TAG("IN1") /* Port 0xe1 */ + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) + + PORT_START_TAG("IN2") /* Read from Port 0xf8 */ + PORT_BIT( 0x0fff, 0x0000, IPT_DIAL ) PORT_SENSITIVITY(60) PORT_KEYDELTA(125) + PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_BUTTON2 ) /* is this used in the game? */ + PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_BUTTON1 ) + PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_UNKNOWN ) + + PORT_START_TAG("IN3") /* Read from Port 0xf8 */ + PORT_BIT( 0x0fff, 0x0000, IPT_DIAL ) PORT_SENSITIVITY(60) PORT_KEYDELTA(125) PORT_COCKTAIL + PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_COCKTAIL + PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_COCKTAIL + PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_UNKNOWN ) +INPUT_PORTS_END + + + +ROM_START( hangonjr ) + ROM_REGION( 0x30000, REGION_CPU1, 0 ) + ROM_LOAD( "rom5.ic7", 0x00000, 0x08000, CRC(d63925a7) SHA1(699f222d9712fa42651c753fe75d7b60e016d3ad) ) /* Fixed Code */ + + /* The following are 8 0x4000 banks that get mapped to reads from 0x8000 - 0xbfff */ + ROM_LOAD( "rom4.ic5", 0x10000, 0x08000, CRC(ee3caab3) SHA1(f583cf92c579d1ca235e8b300e256ba58a04dc90) ) + ROM_LOAD( "rom3.ic4", 0x18000, 0x08000, CRC(d2ba9bc9) SHA1(85cf2a801883bf69f78134fc4d5075134f47dc03) ) + ROM_LOAD( "rom2.ic3", 0x20000, 0x08000, CRC(e14da070) SHA1(f8781f65be5246a23c1f492905409775bbf82ea8) ) + ROM_LOAD( "rom1.ic2", 0x28000, 0x08000, CRC(3810cbf5) SHA1(c8d5032522c0c903ab3d138f62406a66e14a5c69) ) +ROM_END + +ROM_START( ridleofp ) + ROM_REGION( 0x30000, REGION_CPU1, 0 ) + ROM_LOAD( "epr10426.bin", 0x00000, 0x08000, CRC(4404c7e7) SHA1(555f44786976a009d96a6395c9173929ad6138a7) ) /* Fixed Code */ + + /* The following are 8 0x4000 banks that get mapped to reads from 0x8000 - 0xbfff */ + ROM_LOAD( "epr10425.bin", 0x10000, 0x08000, CRC(35964109) SHA1(a7bc64a87b23139b0edb9c3512f47dcf73feb854) ) + ROM_LOAD( "epr10424.bin", 0x18000, 0x08000, CRC(fcda1dfa) SHA1(b8497b04de28fc0d6b7cb0206ad50948cff07840) ) + ROM_LOAD( "epr10423.bin", 0x20000, 0x08000, CRC(0b87244f) SHA1(c88041614735a9b6cba1edde0a11ed413e115361) ) + ROM_LOAD( "epr10422.bin", 0x28000, 0x08000, CRC(14781e56) SHA1(f15d9d89e1ebff36c3867cfc8f0bdf7f6b3c96bc) ) +ROM_END + +ROM_START( transfrm ) + ROM_REGION( 0x30000, REGION_CPU1, 0 ) + ROM_LOAD( "ic7.top", 0x00000, 0x08000, CRC(ccf1d123) SHA1(5ade9b00e2a36d034fafdf1902d47a9a00e96fc4) ) /* Fixed Code */ + + /* The following are 8 0x4000 banks that get mapped to reads from 0x8000 - 0xbfff */ + ROM_LOAD( "epr-7347.ic5", 0x10000, 0x08000, CRC(df0f639f) SHA1(a09a9841b66de246a585be63d911b9a42a323503) ) + ROM_LOAD( "epr-7348.ic4", 0x18000, 0x08000, CRC(0f38ea96) SHA1(d4d421c5d93832e2bc1f22f39dffb6b80f2750bd) ) + ROM_LOAD( "ic3.top", 0x20000, 0x08000, CRC(9d485df6) SHA1(b25f04803c8f7188021f3039aa13aac80d480823) ) + ROM_LOAD( "epr-7350.ic2", 0x28000, 0x08000, CRC(0052165d) SHA1(cf4b5dffa54238e513515b3fc90faa7ce0b65d34) ) +ROM_END + +ROM_START( astrofl ) + ROM_REGION( 0x50000, REGION_CPU1, 0 ) + ROM_LOAD( "epr-7723.ic7", 0x00000, 0x08000, CRC(66061137) SHA1(cb6a2c7864f9f87bbedfd4b1448ad6c2de65d6ca) ) /* encrypted */ + + /* The following are 8 0x4000 banks that get mapped to reads from 0x8000 - 0xbfff */ + ROM_LOAD( "epr-7347.ic5", 0x10000, 0x08000, CRC(df0f639f) SHA1(a09a9841b66de246a585be63d911b9a42a323503) ) + ROM_LOAD( "epr-7348.ic4", 0x18000, 0x08000, CRC(0f38ea96) SHA1(d4d421c5d93832e2bc1f22f39dffb6b80f2750bd) ) + ROM_LOAD( "epr-7349.ic3", 0x20000, 0x08000, CRC(f8c352d5) SHA1(e59565ab6928c67706c6f82f6ea9a64cdfc65a21) ) + ROM_LOAD( "epr-7350.ic2", 0x28000, 0x08000, CRC(0052165d) SHA1(cf4b5dffa54238e513515b3fc90faa7ce0b65d34) ) +ROM_END + + +ROM_START( tetrisse ) + ROM_REGION( 0x30000, REGION_CPU1, 0 ) + ROM_LOAD( "epr12213.7", 0x00000, 0x08000, CRC(ef3c7a38) SHA1(cbb91aef330ab1a37d3e21ecf1d008143d0dd7ec) ) /* Fixed Code */ + + /* The following are 8 0x4000 banks that get mapped to reads from 0x8000 - 0xbfff */ + ROM_LOAD( "epr12212.5", 0x10000, 0x08000, CRC(28b550bf) SHA1(445922a62e8a7360335c754ad70dabbe0208207b) ) + ROM_LOAD( "epr12211.4", 0x18000, 0x08000, CRC(5aa114e9) SHA1(f9fc7fe4d0444a264185e74d2abc8475f0976534) ) + /* ic3 unpopulated */ + /* ic2 unpopulated */ +ROM_END + + +ROM_START( fantzn2 ) + ROM_REGION( 0x50000, REGION_CPU1, 0 ) + ROM_LOAD( "epr-11416.ic7", 0x00000, 0x08000, CRC(76db7b7b) SHA1(d60e2961fc893dcb4445aed5f67515cbd25b610f) ) /* encrypted */ + + ROM_LOAD( "epr-11415.ic5", 0x10000, 0x10000, CRC(57b45681) SHA1(1ae6d0d58352e246a4ec4e1ce02b0417257d5d20) ) + ROM_LOAD( "epr-11413.ic3", 0x20000, 0x10000, CRC(a231dc85) SHA1(45b94fdbde28c02e88546178ef3e8f9f3a96ab86) ) + ROM_LOAD( "epr-11414.ic4", 0x30000, 0x10000, CRC(6f7a9f5f) SHA1(b53aa2eded781c80466a79b7d81383b9a875d0be) ) + ROM_LOAD( "epr-11412.ic2", 0x40000, 0x10000, CRC(b14db5af) SHA1(04c7fb659385438b3d8f9fb66800eb7b6373bda9) ) + + ROM_REGION( 0x2000, REGION_USER1, 0 ) /* MC8123 key */ + ROM_LOAD( "317-0057.key", 0x0000, 0x2000, CRC(ee43d0f0) SHA1(72cb75a4d8352fe372db12046a59ea044360d5c3) ) +ROM_END + +ROM_START( opaopa ) + ROM_REGION( 0x50000, REGION_CPU1, 0 ) + ROM_LOAD( "epr11224.ic7", 0x00000, 0x08000, CRC(024b1244) SHA1(59a522ac3d98982cc4ddb1c81f9584d3da453649) ) /* encrypted */ + + /* The following are 8 0x4000 banks that get mapped to reads from 0x8000 - 0xbfff */ + ROM_LOAD( "epr11223.ic5", 0x10000, 0x08000, CRC(6bc41d6e) SHA1(8997a4ac2a9704f1400d0ec16b259ee496a7efef) ) /* encrypted */ + ROM_LOAD( "epr11222.ic4", 0x18000, 0x08000, CRC(395c1d0a) SHA1(1594bad13e78c5fad4db644cd85a6bac1eaddbad) ) /* encrypted */ + ROM_LOAD( "epr11221.ic3", 0x20000, 0x08000, CRC(4ca132a2) SHA1(cb4e4c01b6ab070eef37c0603190caafe6236ccd) ) /* encrypted */ + ROM_LOAD( "epr11220.ic2", 0x28000, 0x08000, CRC(a165e2ef) SHA1(498ff4c5d3a2658567393378c56be6ed86ac0384) ) /* encrypted */ + + ROM_REGION( 0x2000, REGION_USER1, 0 ) /* MC8123 key */ + ROM_LOAD( "317-0042.key", 0x0000, 0x2000, CRC(d6312538) SHA1(494ac7f080775c21dc7d369e6ea78f3299e6975a) ) +ROM_END + + +static UINT8* vdp2_vram_bank0; +static UINT8* vdp2_vram_bank1; + +static UINT8* vdp1_vram_bank0; +static UINT8* vdp1_vram_bank1; +static UINT8 f7_bank_value; + +static MACHINE_RESET(systeme) +{ + timer_adjust_ptr(vdp1->sms_scanline_timer, attotime_zero, attotime_zero); + timer_adjust_ptr(vdp2->sms_scanline_timer, attotime_zero, attotime_zero); +} + +MACHINE_RESET(megatech_md_sms) +{ + timer_adjust_ptr(md_sms_vdp->sms_scanline_timer, attotime_zero, attotime_zero); +} + +MACHINE_RESET(megatech_bios) +{ + timer_adjust_ptr(vdp1->sms_scanline_timer, attotime_zero, attotime_zero); +} + +static VIDEO_EOF(systeme) +{ + end_of_frame(vdp1); + end_of_frame(vdp2); +} + + +VIDEO_EOF(megatech_md_sms) +{ + end_of_frame(md_sms_vdp); +} + +VIDEO_EOF(megatech_bios) +{ + end_of_frame(vdp1); +} + +VIDEO_UPDATE(megatech_md_sms) +{ + int x,y; + + for (y=0;y<224;y++) + { + UINT16* lineptr = BITMAP_ADDR16(bitmap, y, 0); + UINT16* srcptr = BITMAP_ADDR16(md_sms_vdp->r_bitmap, y, 0); + + for (x=0;x<256;x++) + { + lineptr[x]=srcptr[x]&0x7fff; + } + } + + return 0; +} + + +VIDEO_UPDATE(megatech_bios) +{ + int x,y; + + for (y=0;y<224;y++) + { + UINT16* lineptr = BITMAP_ADDR16(bitmap, y, 0); + UINT16* srcptr = BITMAP_ADDR16(vdp1->r_bitmap, y, 0); + + for (x=0;x<256;x++) + { + lineptr[x]=srcptr[x]&0x7fff; + } + } + + return 0; +} + +static VIDEO_UPDATE(systeme) +{ +// show_tiles(); + int x,y; + + for (y=0;y<192;y++) + { + UINT16* lineptr = BITMAP_ADDR16(bitmap, y, 0); + UINT16* srcptr = BITMAP_ADDR16(vdp1->r_bitmap, y, 0); + + for (x=0;x<256;x++) + { + lineptr[x]=srcptr[x]&0x7fff; + } + + } + + for (y=0;y<192;y++) + { + UINT16* lineptr = BITMAP_ADDR16(bitmap, y, 0); + UINT16* srcptr = BITMAP_ADDR16(vdp2->r_bitmap, y, 0); + + for (x=0;x<256;x++) + { + if(!(srcptr[x]&0x8000)) lineptr[x]=srcptr[x]&0x7fff; + } + } + + + return 0; +} + + +static MACHINE_DRIVER_START( systeme ) + MDRV_CPU_ADD_TAG("z80", Z80, 10738600/2) /* correct for hangonjr, and astroflash/transformer at least */ + MDRV_CPU_PROGRAM_MAP(systeme_readmem,systeme_writemem) + MDRV_CPU_IO_MAP(sms_readport,sms_writeport) + + /* IRQ handled via the timers */ + + MDRV_SCREEN_REFRESH_RATE(60) + MDRV_SCREEN_VBLANK_TIME(DEFAULT_60HZ_VBLANK_DURATION) // Vblank handled manually. + MDRV_MACHINE_RESET(systeme) + + MDRV_VIDEO_ATTRIBUTES(VIDEO_TYPE_RASTER) + MDRV_SCREEN_FORMAT(BITMAP_FORMAT_RGB15) + + MDRV_SCREEN_SIZE(256, 256) +// MDRV_SCREEN_VISIBLE_AREA(0, 255, 0, 223) + MDRV_SCREEN_VISIBLE_AREA(0, 255, 0, 191) + + + MDRV_PALETTE_LENGTH(0x200) + + MDRV_VIDEO_START(sms) + MDRV_VIDEO_UPDATE(systeme) /* Copies a bitmap */ + MDRV_VIDEO_EOF(systeme) /* Used to Sync the timing */ + + /* sound hardware */ + MDRV_SPEAKER_STANDARD_MONO("mono") + + MDRV_SOUND_ADD(SN76496, 3579540) + MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50) + + MDRV_SOUND_ADD(SN76496, 3579540) + MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50) +MACHINE_DRIVER_END + + +static READ8_HANDLER( sms_vdp_2_data_r ) +{ + return vdp_data_r(vdp2); +} + +static WRITE8_HANDLER( sms_vdp_2_data_w ) +{ + vdp_data_w(data, vdp2); +} + +static READ8_HANDLER( sms_vdp_2_ctrl_r ) +{ + return vdp_ctrl_r(vdp2); +} + +static WRITE8_HANDLER( sms_vdp_2_ctrl_w ) +{ + vdp_ctrl_w(data, vdp2); +} + +static WRITE8_HANDLER( segasyse_videoram_w ) +{ + if (f7_bank_value & 0x20) + { // to vdp1 vram + if (f7_bank_value & 0x80) + { + vdp1_vram_bank0[offset] = data; + } + else + { + vdp1_vram_bank1[offset] = data; + } + } + else + { // to vdp2 vram + if (f7_bank_value & 0x40) + { + vdp2_vram_bank0[offset] = data; + } + else + { + vdp2_vram_bank1[offset] = data; + } + } + +} + +static WRITE8_HANDLER( systeme_bank_w ) +{ + int rombank; + f7_bank_value = data; + + rombank = data & 0x0f; + + if (f7_bank_value&0x80) + { + vdp1->vram = vdp1_vram_bank1; + } + else + { + vdp1->vram = vdp1_vram_bank0; + } + + if (f7_bank_value&0x40) + { + vdp2->vram = vdp2_vram_bank1; + } + else + { + vdp2->vram = vdp2_vram_bank0; + } + + //memcpy(sms_rom+0x8000, memory_region(REGION_USER1)+0x10000+rombank*0x4000, 0x4000); + memory_set_bank(1, rombank); + +} + +static WRITE8_HANDLER( sms_sn76496_2_w ) +{ + SN76496_1_w(0, data & 0xff); +} + +static void init_ports_systeme(void) +{ + /* INIT THE PORTS *********************************************************************************************/ + + memory_install_read8_handler (0, ADDRESS_SPACE_IO, 0x7e, 0x7e, 0, 0, sms_vcounter_r); + memory_install_write8_handler(0, ADDRESS_SPACE_IO, 0x7e, 0x7e, 0, 0, sms_sn76496_w); + + + memory_install_write8_handler(0, ADDRESS_SPACE_IO, 0x7b, 0x7b, 0, 0, sms_sn76496_2_w); + + memory_install_write8_handler(0, ADDRESS_SPACE_IO, 0x7f, 0x7f, 0, 0, sms_sn76496_w); + + memory_install_read8_handler (0, ADDRESS_SPACE_IO, 0xba, 0xba, 0, 0, sms_vdp_data_r); + memory_install_write8_handler(0, ADDRESS_SPACE_IO, 0xba, 0xba, 0, 0, sms_vdp_data_w); + memory_install_read8_handler (0, ADDRESS_SPACE_IO, 0xbb, 0xbb, 0, 0, sms_vdp_ctrl_r); + memory_install_write8_handler(0, ADDRESS_SPACE_IO, 0xbb, 0xbb, 0, 0, sms_vdp_ctrl_w); + + + memory_install_read8_handler (0, ADDRESS_SPACE_IO, 0xbe, 0xbe, 0, 0, sms_vdp_2_data_r); + memory_install_write8_handler(0, ADDRESS_SPACE_IO, 0xbe, 0xbe, 0, 0, sms_vdp_2_data_w); + memory_install_read8_handler (0, ADDRESS_SPACE_IO, 0xbf, 0xbf, 0, 0, sms_vdp_2_ctrl_r); + memory_install_write8_handler(0, ADDRESS_SPACE_IO, 0xbf, 0xbf, 0, 0, sms_vdp_2_ctrl_w); + + + memory_install_read8_handler (0, ADDRESS_SPACE_IO, 0xe0, 0xe0, 0, 0, input_port_2_r); + memory_install_read8_handler (0, ADDRESS_SPACE_IO, 0xe1, 0xe1, 0, 0, input_port_3_r); + memory_install_read8_handler (0, ADDRESS_SPACE_IO, 0xe2, 0xe2, 0, 0, input_port_4_r); + memory_install_read8_handler (0, ADDRESS_SPACE_IO, 0xf2, 0xf2, 0, 0, input_port_0_r); + memory_install_read8_handler (0, ADDRESS_SPACE_IO, 0xf3, 0xf3, 0, 0, input_port_1_r); + + + memory_install_write8_handler(0, ADDRESS_SPACE_IO, 0xf7, 0xf7, 0, 0, systeme_bank_w ); + +} + + + +static void init_systeme_map(void) +{ + /* INIT THE MEMMAP / BANKING *********************************************************************************/ + + /* catch any addresses that don't get mapped */ +// memory_install_read8_handler (0, ADDRESS_SPACE_PROGRAM, 0x0000, 0xffff, 0, 0, z80_unmapped_r); +// memory_install_write8_handler(0, ADDRESS_SPACE_PROGRAM, 0x0000, 0xffff, 0, 0, z80_unmapped_w); + + /* fixed rom bank area */ +// sms_rom = auto_malloc(0xc000); +// memory_install_read8_handler (0, ADDRESS_SPACE_PROGRAM, 0x0000, 0xbfff, 0, 0, MRA8_BANK1); +// memory_install_write8_handler(0, ADDRESS_SPACE_PROGRAM, 0x0000, 0x7fff, 0, 0, MWA8_ROM); +// memory_set_bankptr( 1, sms_rom ); + + memory_configure_bank(1, 0, 16, memory_region(REGION_CPU1) + 0x10000, 0x4000); + + /* alternate way of accessing video ram */ + memory_install_write8_handler(0, ADDRESS_SPACE_PROGRAM, 0x8000, 0xbfff, 0, 0, segasyse_videoram_w); + + +// memcpy(sms_rom, memory_region(REGION_USER1), 0x8000); + + /* main ram area */ + sms_mainram = auto_malloc(0x4000); + memory_install_read8_handler (0, ADDRESS_SPACE_PROGRAM, 0xc000, 0xffff, 0, 0, MRA8_BANK2); + memory_install_write8_handler(0, ADDRESS_SPACE_PROGRAM, 0xc000, 0xffff, 0, 0, MWA8_BANK2); + memory_set_bankptr( 2, sms_mainram ); + memset(sms_mainram,0x00,0x4000); + + init_ports_systeme(); +} + +void init_for_megadrive(void) +{ + md_sms_vdp = start_vdp(Machine, GEN_VDP); + md_sms_vdp->set_irq = sms_vdp_cpu1_irq_callback; + md_sms_vdp->is_pal = 0; + md_sms_vdp->sms_total_scanlines = 262; + md_sms_vdp->sms_framerate = 60; + md_sms_vdp->chip_id = 3; +} + + + +DRIVER_INIT( megatech_bios ) +{ +// init_systeme_map(); + + vdp1 = start_vdp(machine, SMS2_VDP); + vdp1->set_irq = sms_vdp_cpu2_irq_callback; + vdp1->is_pal = 0; + vdp1->sms_total_scanlines = 262; + vdp1->sms_framerate = 60; + vdp1->chip_id = 1; + + vdp1_vram_bank0 = vdp1->vram; + vdp1_vram_bank1 = auto_malloc(0x4000); +} + +static DRIVER_INIT( segasyse ) +{ + init_systeme_map(); + + vdp1 = start_vdp(machine, SMS2_VDP); +// vdp1->set_irq = sms_vdp_cpu0_irq_callback; + vdp1->is_pal = 0; + vdp1->sms_total_scanlines = 262; + vdp1->sms_framerate = 60; + vdp1->chip_id = 1; + + vdp1_vram_bank0 = vdp1->vram; + vdp1_vram_bank1 = auto_malloc(0x4000); + + + vdp2 = start_vdp(machine, SMS2_VDP); + vdp2->set_irq = sms_vdp_cpu0_irq_callback; + vdp2->is_pal = 0; + vdp2->sms_total_scanlines = 262; + vdp2->sms_framerate = 60; + vdp2->chip_id = 2; + + vdp2_vram_bank0 = vdp2->vram; + vdp2_vram_bank1 = auto_malloc(0x4000); +} + +/*- Hang On Jr. Specific -*/ +static UINT8 port_fa_last; /* Last thing written to port 0xfa (control related) */ + +static READ8_HANDLER (segae_hangonjr_port_f8_r) +{ + UINT8 temp; + + temp = 0; + + if (port_fa_last == 0x08) /* 0000 1000 */ /* Angle */ + temp = readinputport(4); + + if (port_fa_last == 0x09) /* 0000 1001 */ /* Accel */ + temp = readinputport(5); + + return temp; +} + +static WRITE8_HANDLER (segae_hangonjr_port_fa_w) +{ + /* Seems to write the same pattern again and again bits ---- xx-x used */ + port_fa_last = data; +} + +/*- Riddle of Pythagoras Specific -*/ + +static int port_to_read,last1,last2,diff1,diff2; + +static READ8_HANDLER (segae_ridleofp_port_f8_r) +{ + switch (port_to_read) + { + default: + case 0: return diff1 & 0xff; + case 1: return diff1 >> 8; + case 2: return diff2 & 0xff; + case 3: return diff2 >> 8; + } +} + +static WRITE8_HANDLER (segae_ridleofp_port_fa_w) +{ + /* 0x10 is written before reading the dial (hold counters?) */ + /* 0x03 is written after reading the dial (reset counters?) */ + + port_to_read = (data & 0x0c) >> 2; + + if (data & 1) + { + int curr = readinputport(4); + diff1 = ((curr - last1) & 0x0fff) | (curr & 0xf000); + last1 = curr; + } + if (data & 2) + { + int curr = readinputport(5) & 0x0fff; + diff2 = ((curr - last2) & 0x0fff) | (curr & 0xf000); + last2 = curr; + } +} + +static DRIVER_INIT( ridleofp ) +{ + driver_init_segasyse(machine); + + memory_install_read8_handler(0, ADDRESS_SPACE_IO, 0xf8, 0xf8, 0, 0, segae_ridleofp_port_f8_r); + memory_install_write8_handler(0, ADDRESS_SPACE_IO, 0xfa, 0xfa, 0, 0, segae_ridleofp_port_fa_w); +} + + +static DRIVER_INIT( hangonjr ) +{ + driver_init_segasyse(machine); + + memory_install_read8_handler(0, ADDRESS_SPACE_IO, 0xf8, 0xf8, 0, 0, segae_hangonjr_port_f8_r); + memory_install_write8_handler(0, ADDRESS_SPACE_IO, 0xfa, 0xfa, 0, 0, segae_hangonjr_port_fa_w); +} + +static DRIVER_INIT( opaopa ) +{ + driver_init_segasyse(machine); + + mc8123_decrypt_rom(0, memory_region(REGION_USER1), 1, 8); +} + +static DRIVER_INIT( fantzn2 ) +{ + driver_init_segasyse(machine); + + mc8123_decrypt_rom(0, memory_region(REGION_USER1), 0, 0); +} + +static DRIVER_INIT( astrofl ) +{ + driver_init_segasyse(machine); + + astrofl_decode(); +} + +GAME( 1985, hangonjr, 0, systeme, hangonjr, hangonjr, ROT0, "Sega", "Hang-On Jr.", 0 ) +GAME( 1986, transfrm, 0, systeme, transfrm, segasyse, ROT0, "Sega", "Transformer", 0 ) +GAME( 1986, astrofl, transfrm, systeme, transfrm, astrofl, ROT0, "Sega", "Astro Flash (Japan)", 0 ) +GAME( 1986, ridleofp, 0, systeme, ridleofp, ridleofp, ROT90, "Sega / Nasco", "Riddle of Pythagoras (Japan)", 0 ) +GAME( 1987, opaopa, 0, systeme, opaopa, opaopa, ROT0, "Sega", "Opa Opa (MC-8123, 317-0042)", 0 ) +GAME( 1988, fantzn2, 0, systeme, fantzn2, fantzn2, ROT0, "Sega", "Fantasy Zone 2 (MC-8123, 317-0057)", 0 ) +GAME( 1988, tetrisse, 0, systeme, tetrisse, segasyse, ROT0, "Sega", "Tetris (Japan, System E)", 0 ) |