diff --git a/src/mame/drivers/ms32.c b/src/mame/drivers/ms32.c index e0da94a1880..5fdfa1fb0cf 100644 --- a/src/mame/drivers/ms32.c +++ b/src/mame/drivers/ms32.c @@ -1,8 +1,6 @@ /* Jaleco MegaSystem 32 (Preliminary Driver) ---- this driver is about to undergo a major update - based on actual hardware tests --- - + - hardware tests are needed to establish how the mixing really works (and interrupt source etc.) Used by Jaleco in the Mid-90's this system, based on the V70 processor consisted of a two board set up, the first a standard mainboard and the second a 'cartridge' @@ -45,7 +43,7 @@ MS32 Cartridge Game Roms + Custom Chip -The Custom chip is probably related to the encryption? +The Custom chip provides the encryption Desert War - Custom chip: JALECO SS91022-10 (144 pin PQFP) (located on small plug-in board with) (ID: SE93139 EB91022-30056) Game Paradise - Custom chip: JALECO SS91022-10 9515EV 420201 06441 @@ -75,7 +73,8 @@ ToDo / Notes Z80 + Sound Bits -Re-Add Priorities +Priorities (code in tetrisp2.c doesn't use all of the priority ram.. and doesn't work here) + - some games require completely reversed list processing! Dip switches/inputs in t2m32 and f1superb some games (hayaosi2) don't seeem to have service mode even if it's listed among the dips @@ -83,12 +82,11 @@ service mode is still accessible through F1 though Fix Anything Else (Palette etc.) -Replace CPU divider with Idle skip since we don't know how fast the v70 really is (cpu timing is ignored)... - -Mirror Ram addresses? Not sure about the main "global brightness" control register, I don't think it can make the palette completely black because of kirarast attract mode, so I'm making it cut by 50% at most. + - brightness control also breaks other games in various places, eg gametngk everything going dark + when bomb is used, p47 aces intro? gametngk seems to need some kind of shadow sprites but the only difference in the sprite attributes is one of the priority bits, forcing sprites of that priority to be shadows doesn't work @@ -99,8 +97,6 @@ except gametngk, tetrisp, tp2m32 and gratia. horizontal position of tx and bg tilemaps is off by 1 pixel in some games -There should be NVRAM somewhere, maybe fc000000-fc007fff - bbbxing: some sprite/roz/bg alignment issues gratia: at the beginning of a level it shows the level name in the bottom right corner, scrolling it up @@ -123,18 +119,17 @@ roz layer wrapping: currently it's always ON, breaking places where it gets very repeated on the screen (p47aces, kirarast, bbbxing, gametngk need it OFF). gratia and desertwr need it ON. -there are sprite lag issues, but they might be caused by cpu timing so it's better to leave - them alone until the CPU clock is correct. +there are sprite lag issues - sprites should be framebuffered + +missing clipping window effect in gametngk intro Not Working Games ----------------- -tp2m32 - writes invalid SBR, enables interrupts, crashes (fixed patching the bogus SBR). -f1superb - the road is straight despite the road signs saying otherwise? :-p - - there are 4 unknown ROMS which might be related to the above. - - the handler for IRQ 11 also seems to be valid, the game might need it. - +f1superb - the road is always rendered as straight. + - the game has an extra roz layer and extra roms for it + - there is an unknown maths DSP for protection Jaleco Megasystem 32 Game List - thanks to Yasuhiro --------------------------------------------------- @@ -146,22 +141,23 @@ Tetris Plus 2 (tp2m32) Best Bout Boxing (bbbxing) Wangan Sensou / Desert War (desertwr) Second Earth Gratia (92047-01 version) (gratia) -*Second Earth Gratia (91022-10 version) (gratiaa) -*Super Strong Warriors +*Second Earth Gratia (91022-10 version) (gratiaa) (redump needed) F-1 Super Battle (f1superb) Idol Janshi Su-Chi-Pi 2 (47pie2) Ryuusei Janshi Kirara Star (kirarast) Mahjong Angel Kiss -*Vs. Janshi Brand New Stars +Vs. Janshi Brand New Stars -Hayaoshi Quiz Ouza Ketteisen (hayaosi2) -*Hayaoshi Quiz Nettou Namahousou -*Hayaoshi Quiz Grand Champion Taikai + +Hayaoshi Quiz Nettou Namahousou ( hayaosi3 ) +Hayaoshi Quiz Grand Champion Taikai (hayaosi2) + +Not Dumped: + +Super Strong Warriors -Maybe some more... -Games marked * need dumping / redumping */ @@ -174,7 +170,7 @@ Games marked * need dumping / redumping #include "sound/ymf271.h" #include "includes/ms32.h" -static UINT32 *ms32_fc000000; +static UINT8 *ms32_nvram_8; static UINT32 *ms32_mahjong_input_select; @@ -211,6 +207,7 @@ static CUSTOM_INPUT( mahjong_ctrl_r ) return mj_input & 0xff; } +#if 0 static READ32_HANDLER( ms32_read_inputs3 ) { int a,b,c,d; @@ -220,6 +217,7 @@ static READ32_HANDLER( ms32_read_inputs3 ) d = (input_port_read(space->machine, "AN0") - 0xb0) & 0xff; return a << 24 | b << 16 | c << 8 | d << 0; } +#endif static WRITE32_HANDLER( ms32_sound_w ) { @@ -245,44 +243,66 @@ static WRITE32_HANDLER( reset_sub_w ) /********** MEMORY MAP **********/ -/* some games games test more ram than others .. ram areas with closed comments before -the lines get tested by various games but I'm not sure are really used, maybe they're -mirror addresses? */ - -/* -p47 aces: -there are bugs in the test routine, so it checks twice the amount of RAM -actually present, relying on mirror addresses. -See how ASCII and SCROLL overlap. -SCRATCH RAM fee00000-fee1ffff -ASCII RAM fec00000-fec0ffff (actually fec00000-fec07fff ?) -SCROLL RAM fec08000-fec17fff (actually fec08000-fec0ffff ?) -ROTATE RAM fe000000-fe03ffff (actually fe000000-fe01ffff ?) -OBJECT RAM fe800000-fe87ffff (actually fe800000-fe83ffff ?) -COLOR RAM fd400000-fd40ffff (this one is actually larger than tested) -PRIORITY RAM fd180000-fd1bffff (actually fd180000-fd19ffff ?) -SOUND RAM - -This applies to most of the other games. -Also, gametngk uses mirror addresses for the background during gameplay, without -support for them bad tiles appear in the bg. -*/ - static WRITE32_HANDLER( pip_w ) { if (data) popmessage("fce00a7c = %02x",data); } +extern tilemap *ms32_tx_tilemap, *ms32_roz_tilemap, *ms32_bg_tilemap; +extern UINT8* ms32_priram_8; +extern UINT16* ms32_palram_16; +extern UINT16* ms32_rozram_16; +extern UINT16* ms32_lineram_16; +extern UINT16* ms32_sprram_16; +extern UINT16* ms32_txram_16; +extern UINT16* ms32_bgram_16; + +static READ8_HANDLER( ms32_nvram_r8 ) { return ms32_nvram_8[offset]; } +static WRITE8_HANDLER( ms32_nvram_w8 ) { ms32_nvram_8[offset] = data; } +static READ8_HANDLER( ms32_priram_r8 ) { return ms32_priram_8[offset]; } +static WRITE8_HANDLER( ms32_priram_w8 ) { ms32_priram_8[offset] = data; } +static READ16_HANDLER( ms32_palram_r16 ) { return ms32_palram_16[offset]; } +static WRITE16_HANDLER( ms32_palram_w16 ) { COMBINE_DATA(&ms32_palram_16[offset]); } +static READ16_HANDLER( ms32_rozram_r16 ) { return ms32_rozram_16[offset]; } +static WRITE16_HANDLER( ms32_rozram_w16 ) { COMBINE_DATA(&ms32_rozram_16[offset]); tilemap_mark_tile_dirty(ms32_roz_tilemap,offset/2); } +static READ16_HANDLER( ms32_lineram_r16 ) { return ms32_lineram_16[offset]; } +static WRITE16_HANDLER( ms32_lineram_w16 ) { COMBINE_DATA(&ms32_lineram_16[offset]); } +static READ16_HANDLER( ms32_sprram_r16 ) { return ms32_sprram_16[offset]; } +static WRITE16_HANDLER( ms32_sprram_w16 ) { COMBINE_DATA(&ms32_sprram_16[offset]); } +static READ16_HANDLER( ms32_txram_r16 ) { return ms32_txram_16[offset]; } +static WRITE16_HANDLER( ms32_txram_w16 ) { COMBINE_DATA(&ms32_txram_16[offset]); tilemap_mark_tile_dirty(ms32_tx_tilemap,offset/2); } +static READ16_HANDLER( ms32_bgram_r16 ) { return ms32_bgram_16[offset]; } +static WRITE16_HANDLER( ms32_bgram_w16 ) { COMBINE_DATA(&ms32_bgram_16[offset]); tilemap_mark_tile_dirty(ms32_bg_tilemap,offset/2); } + + static ADDRESS_MAP_START( ms32_map, ADDRESS_SPACE_PROGRAM, 32 ) - AM_RANGE(0x00000000, 0x001fffff) AM_ROM - AM_RANGE(0xfc000000, 0xfc007fff) AM_RAM AM_BASE(&ms32_fc000000) // NVRAM? + /* RAM areas verified by testing on real hw - usually accessed at the 0xfc000000 + mirror */ + AM_RANGE(0xc0000000, 0xc0007fff) AM_READWRITE8 (ms32_nvram_r8, ms32_nvram_w8, 0x000000ff) AM_MIRROR(0x3c1fe000) // nvram is 8-bit wide, 0x2000 in size */ +/* AM_RANGE(0xc0008000, 0xc01fffff) // mirrors of nvramram, handled above */ + AM_RANGE(0xc1180000, 0xc1187fff) AM_READWRITE8 (ms32_priram_r8, ms32_priram_w8, 0x000000ff) AM_MIRROR(0x3c038000) /* priram is 8-bit wide, 0x2000 in size */ +/* AM_RANGE(0xc1188000, 0xc11bffff) // mirrors of priram, handled above */ + AM_RANGE(0xc1400000, 0xc143ffff) AM_READWRITE16(ms32_palram_r16, ms32_palram_w16, 0x0000ffff) AM_MIRROR(0x3c1c0000) /* palram is 16-bit wide, 0x20000 in size */ +/* AM_RANGE(0xc1440000, 0xc145ffff) // mirrors of palram, handled above */ + AM_RANGE(0xc2000000, 0xc201ffff) AM_READWRITE16(ms32_rozram_r16, ms32_rozram_w16, 0x0000ffff) AM_MIRROR(0x3c1e0000) /* rozram is 16-bit wide, 0x10000 in size */ +/* AM_RANGE(0xc2020000, 0xc21fffff) // mirrors of rozram, handled above */ + AM_RANGE(0xc2200000, 0xc2201fff) AM_READWRITE16(ms32_lineram_r16,ms32_lineram_w16,0x0000ffff) AM_MIRROR(0x3c1fe000) /* lineram is 16-bit wide, 0x1000 in size */ +/* AM_RANGE(0xc2202000, 0xc23fffff) // mirrors of lineram, handled above */ + AM_RANGE(0xc2800000, 0xc283ffff) AM_READWRITE16(ms32_sprram_r16, ms32_sprram_w16, 0x0000ffff) AM_MIRROR(0x3c1c0000) /* spriteram is 16-bit wide, 0x20000 in size */ +/* AM_RANGE(0xc2840000, 0xc29fffff) // mirrors of sprram, handled above */ + AM_RANGE(0xc2c00000, 0xc2c07fff) AM_READWRITE16(ms32_txram_r16, ms32_txram_w16, 0x0000ffff) AM_MIRROR(0x3c1f0000) /* txram is 16-bit wide, 0x4000 in size */ + AM_RANGE(0xc2c08000, 0xc2c0ffff) AM_READWRITE16(ms32_bgram_r16, ms32_bgram_w16, 0x0000ffff) AM_MIRROR(0x3c1f0000) /* bgram is 16-bit wide, 0x4000 in size */ +/* AM_RANGE(0xc2c10000, 0xc2dfffff) // mirrors of txram / bg, handled above */ + AM_RANGE(0xc2e00000, 0xc2e1ffff) AM_RAM AM_BASE(&ms32_mainram) AM_MIRROR(0x3c0e0000) /* mainram is 32-bit wide, 0x20000 in size */ + AM_RANGE(0xc3e00000, 0xc3ffffff) AM_ROMBANK(1) AM_MIRROR(0x3c000000) // ROM is 32-bit wide, 0x200000 in size */ + + + + /* todo: clean up the mapping of these */ AM_RANGE(0xfc800000, 0xfc800003) AM_READNOP /* sound? */ AM_RANGE(0xfc800000, 0xfc800003) AM_WRITE(ms32_sound_w) /* sound? */ - AM_RANGE(0xfcc00004, 0xfcc00007) AM_READ_PORT("INPUTS") AM_RANGE(0xfcc00010, 0xfcc00013) AM_READ_PORT("DSW") - AM_RANGE(0xfce00034, 0xfce00037) AM_WRITENOP // irq ack? AM_RANGE(0xfce00038, 0xfce0003b) AM_WRITE(reset_sub_w) AM_RANGE(0xfce00050, 0xfce0005f) AM_WRITENOP // watchdog? I haven't investigated @@ -293,39 +313,24 @@ static ADDRESS_MAP_START( ms32_map, ADDRESS_SPACE_PROGRAM, 32 ) /**/AM_RANGE(0xfce00a00, 0xfce00a17) AM_RAM AM_BASE(&ms32_tx_scroll) /* tx layer scroll */ /**/AM_RANGE(0xfce00a20, 0xfce00a37) AM_RAM AM_BASE(&ms32_bg_scroll) /* bg layer scroll */ AM_RANGE(0xfce00a7c, 0xfce00a7f) AM_WRITE(pip_w) // ??? layer related? seems to be always 0 -// AM_RANGE(0xfce00800, 0xfce0085f) // f1superb, roz #2 control? // AM_RANGE(0xfce00e00, 0xfce00e03) coin counters + something else - AM_RANGE(0xfd000000, 0xfd000003) AM_READ(ms32_sound_r) - AM_RANGE(0xfd0e0000, 0xfd0e0003) AM_READ(ms32_read_inputs3) /* analog controls in f1superb? */ + AM_RANGE(0xfd1c0000, 0xfd1c0003) AM_WRITEONLY AM_BASE(&ms32_mahjong_input_select) + +ADDRESS_MAP_END + +/* F1 Super Blast has an extra ROZ tilemap, and am unknown maths chip (mcu?) handling perspective calculations for the road / corners etc. */ +/* it should use it's own memory map */ + +// AM_RANGE(0xfce00800, 0xfce0085f) // f1superb, roz #2 control? ///**/AM_RANGE(0xfd104000, 0xfd105fff) AM_RAM /* f1superb */ ///**/AM_RANGE(0xfd144000, 0xfd145fff) AM_RAM /* f1superb */ - - AM_RANGE(0xfd180000, 0xfd19ffff) AM_READWRITE(ms32_priram_r,ms32_priram_w) AM_BASE(&ms32_priram) /* priority ram */ - AM_RANGE(0xfd1a0000, 0xfd1bffff) AM_READWRITE(ms32_priram_r,ms32_priram_w) /* mirror only used by memory test in service mode */ - AM_RANGE(0xfd1c0000, 0xfd1c0003) AM_WRITEONLY AM_BASE(&ms32_mahjong_input_select) - - AM_RANGE(0xfd400000, 0xfd43ffff) AM_RAM_WRITE(ms32_palram_w) AM_BASE(&ms32_palram) /* Palette */ ///**/AM_RANGE(0xfd440000, 0xfd47ffff) AM_RAM /* f1superb color */ - ///**/AM_RANGE(0xfdc00000, 0xfdc006ff) AM_RAM /* f1superb */ ///**/AM_RANGE(0xfde00000, 0xfde01fff) AM_RAM /* f1superb lineram #2? */ - AM_RANGE(0xfe000000, 0xfe01ffff) AM_READWRITE(ms32_rozram_r,ms32_rozram_w) AM_BASE(&ms32_rozram) /* roz layer */ - AM_RANGE(0xfe020000, 0xfe03ffff) AM_READWRITE(ms32_rozram_r,ms32_rozram_w) /* mirror only used by memory test in service mode */ - AM_RANGE(0xfe1ffc88, 0xfe1fffff) AM_WRITENOP /* gratia writes here before falling into lineram, could be a mirror */ - AM_RANGE(0xfe200000, 0xfe201fff) AM_READWRITE(ms32_lineram_r,ms32_lineram_w) AM_BASE(&ms32_lineram) /* line ram for roz layer */ ///**/AM_RANGE(0xfe202000, 0xfe2fffff) AM_RAM /* f1superb vram */ - - AM_RANGE(0xfe800000, 0xfe83ffff) AM_READWRITE(ms32_spram_r,ms32_spram_w) AM_BASE(&ms32_spram) /* sprites */ - AM_RANGE(0xfe840000, 0xfe87ffff) AM_READWRITE(ms32_spram_r,ms32_spram_w) /* mirror only used by memory test in service mode */ - AM_RANGE(0xfec00000, 0xfec07fff) AM_READWRITE(ms32_txram_r,ms32_txram_w) AM_BASE(&ms32_txram) /* tx layer */ - AM_RANGE(0xfec08000, 0xfec0ffff) AM_READWRITE(ms32_bgram_r,ms32_bgram_w) AM_BASE(&ms32_bgram) /* bg layer */ - AM_RANGE(0xfec10000, 0xfec17fff) AM_READWRITE(ms32_txram_r,ms32_txram_w) /* mirror only used by memory test in service mode */ - AM_RANGE(0xfec18000, 0xfec1ffff) AM_READWRITE(ms32_bgram_r,ms32_bgram_w) /* mirror used by gametngk at the beginning of the game */ - AM_RANGE(0xfee00000, 0xfee1ffff) AM_RAM AM_BASE(&ms32_mainram) - AM_RANGE(0xffe00000, 0xffffffff) AM_ROMBANK(1) -ADDRESS_MAP_END +// AM_RANGE(0xfd0e0000, 0xfd0e0003) AM_READ(ms32_read_inputs3) /* analog controls in f1superb? */ /************************************* * @@ -1184,12 +1189,12 @@ static MACHINE_DRIVER_START( ms32 ) MDRV_SCREEN_ADD("screen", RASTER) MDRV_SCREEN_REFRESH_RATE(60) MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0)) - MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16) + MDRV_SCREEN_FORMAT(BITMAP_FORMAT_RGB32) MDRV_SCREEN_SIZE(40*8, 28*8) MDRV_SCREEN_VISIBLE_AREA(0*8, 40*8-1, 0*8, 28*8-1) MDRV_GFXDECODE(ms32) - MDRV_PALETTE_LENGTH(0x8000) + MDRV_PALETTE_LENGTH(0x10000) MDRV_VIDEO_START(ms32) MDRV_VIDEO_UPDATE(ms32) @@ -2121,10 +2126,16 @@ static void configure_banks(running_machine *machine) memory_configure_bank(machine, 5, 0, 16, memory_region(machine, "audiocpu") + 0x14000, 0x4000); } +static DRIVER_INIT( ms32_common ) +{ + ms32_nvram_8 = auto_alloc_array(machine, UINT8, 0x2000); + configure_banks(machine); +} + /* SS91022-10: desertwr, gratiaa, tp2m32, gametngk */ static DRIVER_INIT (ss91022_10) { - configure_banks(machine); + DRIVER_INIT_CALL(ms32_common); ms32_rearrange_sprites(machine, "gfx1"); decrypt_ms32_tx(machine, 0x00000,0x35, "gfx4"); decrypt_ms32_bg(machine, 0x00000,0xa3, "gfx3"); @@ -2133,7 +2144,7 @@ static DRIVER_INIT (ss91022_10) /* SS92046_01: bbbxing, f1superb, tetrisp, hayaosi2 */ static DRIVER_INIT (ss92046_01) { - configure_banks(machine); + DRIVER_INIT_CALL(ms32_common); ms32_rearrange_sprites(machine, "gfx1"); decrypt_ms32_tx(machine, 0x00020,0x7e, "gfx4"); decrypt_ms32_bg(machine, 0x00001,0x9b, "gfx3"); @@ -2142,7 +2153,7 @@ static DRIVER_INIT (ss92046_01) /* SS92047-01: gratia, kirarast */ static DRIVER_INIT (ss92047_01) { - configure_banks(machine); + DRIVER_INIT_CALL(ms32_common); ms32_rearrange_sprites(machine, "gfx1"); decrypt_ms32_tx(machine, 0x24000,0x18, "gfx4"); decrypt_ms32_bg(machine, 0x24000,0x55, "gfx3"); @@ -2151,7 +2162,7 @@ static DRIVER_INIT (ss92047_01) /* SS92048-01: p47aces, 47pie2, 47pie2o */ static DRIVER_INIT (ss92048_01) { - configure_banks(machine); + DRIVER_INIT_CALL(ms32_common); ms32_rearrange_sprites(machine, "gfx1"); decrypt_ms32_tx(machine, 0x20400,0xd6, "gfx4"); decrypt_ms32_bg(machine, 0x20400,0xd4, "gfx3"); @@ -2205,3 +2216,295 @@ GAME( 1996, wpksocv2, 0, ms32, wpksocv2, ss92046_01, ROT0, "Jaleco", "W /* these boot and show something */ GAME( 1994, f1superb, 0, ms32, f1superb, f1superb, ROT0, "Jaleco", "F1 Super Battle", GAME_NOT_WORKING | GAME_NO_SOUND | GAME_SUPPORTS_SAVE ) + +/* Notes from Charles MacDonald + +---------------------------------------------------------------------------- + Z80 communication + ---------------------------------------------------------------------------- + + The system has two 8-bit registers which store bytes going from the Z80 + to the V70 and vice-versa. + + V70 side + + $FC800000 : Writes load the Z80 sound latch and trigger a NMI. + + Reads return D31-D16 = open bus, D15-D0 = $FFFF. + + $FD000000 : Reads return D31-D16 = open bus, D15-D8 = $FF, and + D7-D0 = V70 sound latch, inverted. + + Writes halt the system. + + Z80 side + + $3F10 : Reads return the contents of the Z80 sound latch, inverted. + Writes load the V70 sound latch. + + To handle the inversion of sound latch data, both CPUs should invert the + data read from their respective read addresses. + + *** Does NMI stay low such that further NMIs can't occur until it's ACK'd? + + Well, reading 3F10-3F1F allows further NMIs which are otherwise masked. + + Is /NMI line really physically held low during this time? + Or is there just a flip-flop that remains set until read, which + gates NMI? + + *** Does $3F10 cause interrupt on V60 side when accessed? Or $3F20? + Could 3F20 be a V70-side interrupt request clear register? + + ---------------------------------------------------------------------------- + Sound reset register + ---------------------------------------------------------------------------- + + Writing a '1' to bit 0 of $FCE00038 temporarily pulses the Z80 /RESET pin + low for approximately one second, at which point it goes high again and the + Z80 resumes operation. + + Setting this bit does *not* keep the Z80 reset for the duration that + it is set. It's function is that of a trigger for an automatically timed + reset pulse. + + *** Measure /RESET pulse width in units of Z80 clocks. + + ---------------------------------------------------------------------------- + V70 memory map + ---------------------------------------------------------------------------- + + Overview + + The hardware maps memory and other devices to a 64MB chunk that is + repeatedly mirrored throughout the last 1GB of the address space. + + The system is set up so the V70 is halted when it accesses an unused + memory address or accesses it in an unintended way (reading write-only + locations, writing to read-only locations). Shortly thereafter the + watchdog resets the system due to inactivity. + + The V70 data bus is 32-bit but is connected to a mix of 8, 16, and 32-bit + hardware. The undriven data bus bits tend to float high, though my + board had a lot of extra pull-up resistors someone added in one of + the expansion sockets. I'll try to give approximate garbage values read + from these locations when possible. + + V70 memory map + + C0000000-FBFFFFFF : Mirror of FC000000-FFFFFFFF + + Range Acc Repeat Size Width Description + + FC000000-FC1FFFFF : R/W : 32K : 8K : 8 : NVRAM + FC600000-FC7FFFFF : R/W : --- : --- : -- : Unused (return $FFFFFFFF) + FC800000-FC9FFFFF : R/W : 4b : : 16 : Z80 sound latch (out) + FCC00000-FCDFFFFF : R/W : 32b : : 32 : I/O area + FCE00000-FCFFFFFF : W/O : 8K : 4K : 16 : Video registers + FD000000-FD03FFFF : R/O : 4b : : 16 : Z80 sound latch (in) + FD180000-FD1BFFFF : R/W : 32K : 8K : 8 : Priority RAM + FD400000-FD5FFFFF : R/W : 256K : 128K : 16 : Color RAM + FE000000-FE1FFFFF : R/W : 128K : 64K : 16 : Rotate RAM + FE200000-FE3FFFFF : R/W : 8K : 4K : 16 : Line RAM + FE800000-FE9FFFFF : R/W : 256K : 128K : 16 : Object RAM + FEC00000-FEDFFFFF : R/W : 64K : 32K : 16 : ASCII RAM / Scroll RAM + FEE00000-FEEFFFFF : R/W : 128K : 128K : 32 : Work RAM + FF000000-FFFFFFFF : R/O : 2MB : 2MB : 32 : Program ROM + + For example, the object RAM is 128Kx16, mapped to D15-D0 of each word. + This corresponds to a 256K space (128K x 32-bits, 16 of which are used) + that repeats every 256K within FE800000-FE9FFFFF. + + 1.) Data written to the LSB is stored inverted in $3F10 and triggers NMI. + Writing to D15-D8 does nothing and value read is $FF. + Writing to D31-D16 resets the machine, values read are open bus (opcodes). + + All items listed are repeatedly mirrored throughout the memory ranges + they are assigned to. + + This is the memory map for a Desert War boardset. Other games can add + additional hardware on the ROM board which take up memory ranges not listed + here. Consider it to be the memory map for a stock Mega System 32 mainboard. + + ---------------------------------------------------------------------------- + I/O ports + ---------------------------------------------------------------------------- + + The I/O area consists of 16 word locations that are mirrored repeatedly + throughout the range they are mapped to: + + FCC00000 : ? + FCC00004 : Player 1, 2 and control panel inputs + FCC00008 : ? + FCC0000C : ? + FCC00010 : DIP switch inputs + FCC00014 : ? + FCC00018 : ? + FCC0001C : ? + + Input details + + FCC00004 : ---- ---- ---- ---- ---- ---- 4321 rldu : 1P buttons, joystick + : ---- ---- ---- ---- 4321 rldu ---- ---- : 2P buttons, joystick + : ---- ---- ---- --21 ---- ---- ---- ---- : 2P coin, 1P coin + : ---- ---- ---- ts-- ---- ---- ---- ---- : Test, service + : ---- ---- --21 ---- ---- ---- ---- ---- : 2P start, 1P start + + * All inputs are active-high (1= switch released, 0= switch pressed) + + * When the TILT input is asserted, the system is reset. This continues + until TILT is released. The state of TILT cannot be read. + + FCC00010 : ---- ---- ---- ---- ---- ---- 1234 5678 : DIP SW2 #1-8 + : ---- ---- ---- ---- 1234 5678 ---- ---- : DIP SW1 #1-8 + : ---- ---- 1234 5678 ---- ---- ---- ---- : DIP SW3 #1-8 + + * All inputs are active-low (1= switch OFF, 0= switch ON) + + + ---------------------------------------------------------------------------- + System and video registers + ---------------------------------------------------------------------------- + + This area is 8K long and repeats every 8K. All registers are write-only + and are mapped to D15-D0 of each word. + + $FCE00000 : Screen mode control + + D0 : Dot clock control (1= 24 KHz?, 0= 15 KHz) + + $FCE00004 : Horizontal timing + $FCE00008 : Horizontal timing + $FCE0000C : Horizontal timing + $FCE00010 : Horizontal viewport start + $FCE00014 : Frame height + $FCE00018 : Display height + $FCE0001C : Horizontal positioning + $FCE00020 : Fine positioning adjust + + $FCE00045 : IRQ acknowledge + $FCE00038 : Sound CPU reset + $FCE00050 : Watchdog reset + $FCE006xx : ROZ + + $FCE00A00 : Text layer horizontal scroll #1 + $FCE00A04 : Text layer vertical scroll #1 + $FCE00A08 : Text layer horizontal scroll #2 + $FCE00A0C : Text layer vertical scroll #2 + + $FCE00A2x : BG layer + $FCE00A7C : Layer related + $FCE00Exx : Coin meter + lockout + + ---------------------------------------------------------------------------- + NVRAM + ---------------------------------------------------------------------------- + + NVRAM is 8K, occupying D7-D0 of each word. It is mirrored every 8K-words + (32K bytes) in memory. + + Remaining data bits return $FFFFF4xx. + + The NVRAM consists of a low-power 8K SRAM connected to a .1F capacitor for + short-term data retention and a CR2032 lithium battery for long-term + retention. It also has a write inhibit circuit to protect RAM from spurious + writes when the voltage drops low enough to trigger a system reset. + During normal operation the write protection is transparent to the + programmer and the SRAM can be accessed normally. + + ---------------------------------------------------------------------------- + Priority RAM + ---------------------------------------------------------------------------- + + Priority RAM is 8K, occupying D7-D0 of each word. It is mirrored + every 8K-words (32K bytes) in memory. + + Remaining data bits return $00FFFFxx. + + Note that the priority RAM chip is actually 32K. The upper address lines + are tied low or high, so perhaps priority RAM is banked. + + ---------------------------------------------------------------------------- + Color RAM + ---------------------------------------------------------------------------- + + Color RAM is implemented with three 32Kx8 SRAMs. Every eight-byte area + within color RAM addresses one location in color RAM. The red and green + color RAMs are connected in parallel to D15-D0 respectively for even words, + and the blue color RAM is connected to D7-D0 for odd words: + + MSB LSB + +$00 : ---- ---- ---- ---- rrrr rrrr gggg gggg : Red, green components + +$04 : ---- ---- ---- ---- ---- ---- bbbb bbbb : Blue component + + - = Bit isn't used. Usually returns '1'. + + The color RAM area is 256K in size (32K entries x 8 bytes per entry) and + is mirrored every 256K bytes in memory. + + ---------------------------------------------------------------------------- + Rotate RAM + ---------------------------------------------------------------------------- + + Rotate RAM is 64K, occuping D15-D0 of each word. It is mirrored every + 64K-words (128K bytes) in memory. + + Remaining data bits return $00FFxxxx or $0000xxxx randomly. + + ---------------------------------------------------------------------------- + Object RAM + ---------------------------------------------------------------------------- + + Object RAM is 128K, occuping D15-D0 of each word. It is mirrored every + 128K-words (256K bytes) in memory. + + Remaining data bits return $FFFFxxxx. + + ---------------------------------------------------------------------------- + ASCII / Scroll RAM + ---------------------------------------------------------------------------- + + ASCII / Scroll RAM is 32K, occupying D15-D0 of each word. It is mirrored + every 64K-words (128K bytes) in memory. + + Remaining data bits return $0000xxxx. + + ---------------------------------------------------------------------------- + Work RAM + ---------------------------------------------------------------------------- + + Work RAM is 128K, occupying D31-D0 of each word. It is mirrored every 128K + bytes in memory. + + ---------------------------------------------------------------------------- + Program ROM + ---------------------------------------------------------------------------- + + Program ROM is 512K, occupying D31-D0 of each word. It is mirrored every + 512K bytes in memory. + + ---------------------------------------------------------------------------- + CPU information + ---------------------------------------------------------------------------- + + Main CPU: NEC uPD70632GD-20 (200-pin PQFP, 20 MHz) + + * The value of PIR for this particular chip is $00007007. + + * The instruction MOV.D with a register operand uses the register + pair "rn:rn+1" as the source data. R31 is a special case; the second + register of the pair is still R31 rather than wrapping to R0. + + mov.d r2, [r0] ; Write pair R2:R3 to [R0] + mov.d r3, [r0] ; Write pair R3:R4 to [R0] + mov.d r31, [r0] ; Write pair R31:R31 to [R0] + + Using the immediate or quick immediate addressing mode for the source + operand causes an Addressing Mode exception, just like the uPD70616. + + Sound CPU: Zilog Z80840008PSC (40-pin DIP, 8 MHz) + + * NMOS type. Undocumented instruction "out (c), 0" functions normally. + + + */ diff --git a/src/mame/drivers/tetrisp2.c b/src/mame/drivers/tetrisp2.c index 8cc2e89d6b2..8c328c2bd60 100644 --- a/src/mame/drivers/tetrisp2.c +++ b/src/mame/drivers/tetrisp2.c @@ -299,6 +299,7 @@ static WRITE16_HANDLER( tetrisp2_coincounter_w ) } + /*************************************************************************** @@ -312,7 +313,7 @@ static ADDRESS_MAP_START( tetrisp2_map, ADDRESS_SPACE_PROGRAM, 16 ) AM_RANGE(0x100000, 0x103fff) AM_RAM AM_BASE(&spriteram16) AM_SIZE(&spriteram_size) // Object RAM AM_RANGE(0x104000, 0x107fff) AM_RAM // Spare Object RAM AM_RANGE(0x108000, 0x10ffff) AM_RAM // Work RAM - AM_RANGE(0x200000, 0x23ffff) AM_RAM_WRITE(tetrisp2_priority_w) AM_BASE(&tetrisp2_priority) // Priority + AM_RANGE(0x200000, 0x23ffff) AM_READWRITE8(tetrisp2_priority_r, tetrisp2_priority_w, 0x00ff) AM_RANGE(0x300000, 0x31ffff) AM_RAM_WRITE(tetrisp2_palette_w) AM_BASE(&paletteram16) // Palette AM_RANGE(0x400000, 0x403fff) AM_RAM_WRITE(tetrisp2_vram_fg_w) AM_BASE(&tetrisp2_vram_fg) // Foreground AM_RANGE(0x404000, 0x407fff) AM_RAM_WRITE(tetrisp2_vram_bg_w) AM_BASE(&tetrisp2_vram_bg) // Background @@ -369,7 +370,8 @@ static ADDRESS_MAP_START( nndmseal_map, ADDRESS_SPACE_PROGRAM, 16 ) AM_RANGE(0x100000, 0x103fff) AM_RAM AM_BASE(&spriteram16) AM_SIZE(&spriteram_size ) // Object RAM AM_RANGE(0x104000, 0x107fff) AM_RAM // Spare Object RAM AM_RANGE(0x108000, 0x10ffff) AM_RAM // Work RAM - AM_RANGE(0x200000, 0x23ffff) AM_READWRITE(nndmseal_priority_r, SMH_RAM) AM_BASE(&tetrisp2_priority ) // Priority + AM_RANGE(0x200000, 0x23ffff) AM_WRITE8(tetrisp2_priority_w, 0x00ff) // Priority + AM_RANGE(0x200000, 0x23ffff) AM_READ(nndmseal_priority_r) AM_RANGE(0x300000, 0x31ffff) AM_RAM_WRITE(tetrisp2_palette_w) AM_BASE(&paletteram16 ) // Palette AM_RANGE(0x400000, 0x403fff) AM_RAM_WRITE(tetrisp2_vram_fg_w) AM_BASE(&tetrisp2_vram_fg ) // Foreground AM_RANGE(0x404000, 0x407fff) AM_RAM_WRITE(tetrisp2_vram_bg_w) AM_BASE(&tetrisp2_vram_bg ) // Background @@ -414,7 +416,7 @@ static ADDRESS_MAP_START( rockn1_map, ADDRESS_SPACE_PROGRAM, 16 ) AM_RANGE(0x100000, 0x103fff) AM_RAM AM_BASE(&spriteram16) AM_SIZE(&spriteram_size) // Object RAM AM_RANGE(0x104000, 0x107fff) AM_RAM // Spare Object RAM AM_RANGE(0x108000, 0x10ffff) AM_RAM // Work RAM - AM_RANGE(0x200000, 0x23ffff) AM_RAM_WRITE(rockn_priority_w) AM_BASE(&tetrisp2_priority) // Priority + AM_RANGE(0x200000, 0x23ffff) AM_READWRITE8(tetrisp2_priority_r, rockn_priority_w, 0x00ff) // Priority AM_RANGE(0x300000, 0x31ffff) AM_RAM_WRITE(tetrisp2_palette_w) AM_BASE(&paletteram16) // Palette AM_RANGE(0x400000, 0x403fff) AM_RAM_WRITE(tetrisp2_vram_fg_w) AM_BASE(&tetrisp2_vram_fg) // Foreground AM_RANGE(0x404000, 0x407fff) AM_RAM_WRITE(tetrisp2_vram_bg_w) AM_BASE(&tetrisp2_vram_bg) // Background @@ -448,7 +450,7 @@ static ADDRESS_MAP_START( rockn2_map, ADDRESS_SPACE_PROGRAM, 16 ) AM_RANGE(0x100000, 0x103fff) AM_RAM AM_BASE(&spriteram16) AM_SIZE(&spriteram_size) // Object RAM AM_RANGE(0x104000, 0x107fff) AM_RAM // Spare Object RAM AM_RANGE(0x108000, 0x10ffff) AM_RAM // Work RAM - AM_RANGE(0x200000, 0x23ffff) AM_RAM_WRITE(rockn_priority_w) AM_BASE(&tetrisp2_priority) // Priority + AM_RANGE(0x200000, 0x23ffff) AM_READWRITE8(tetrisp2_priority_r, rockn_priority_w, 0x00ff) // Priority AM_RANGE(0x300000, 0x31ffff) AM_RAM_WRITE(tetrisp2_palette_w) AM_BASE(&paletteram16) // Palette AM_RANGE(0x500000, 0x50ffff) AM_RAM // Line AM_RANGE(0x600000, 0x60ffff) AM_RAM_WRITE(tetrisp2_vram_rot_w) AM_BASE(&tetrisp2_vram_rot) // Rotation @@ -482,7 +484,7 @@ static ADDRESS_MAP_START( rocknms_main_map, ADDRESS_SPACE_PROGRAM, 16 ) AM_RANGE(0x100000, 0x103fff) AM_RAM AM_BASE(&spriteram16) AM_SIZE(&spriteram_size) // Object RAM AM_RANGE(0x104000, 0x107fff) AM_RAM // Spare Object RAM AM_RANGE(0x108000, 0x10ffff) AM_RAM // Work RAM - AM_RANGE(0x200000, 0x23ffff) AM_RAM_WRITE(rockn_priority_w) AM_BASE(&tetrisp2_priority) // Priority + AM_RANGE(0x200000, 0x23ffff) AM_READWRITE8(tetrisp2_priority_r, rockn_priority_w, 0x00ff) // Priority AM_RANGE(0x300000, 0x31ffff) AM_RAM_WRITE(tetrisp2_palette_w) AM_BASE(&paletteram16) // Palette // AM_RANGE(0x500000, 0x50ffff) AM_RAM // Line AM_RANGE(0x600000, 0x60ffff) AM_RAM_WRITE(tetrisp2_vram_rot_w) AM_BASE(&tetrisp2_vram_rot) // Rotation @@ -1003,19 +1005,24 @@ static const gfx_layout layout_16x16x8 = 16*16*8 }; + +/* sprites are contained in 256x256 "tiles" */ +static GFXLAYOUT_RAW( spritelayout, 8, 256, 256, 256*8, 256*256*8 ) + + static GFXDECODE_START( tetrisp2 ) - GFXDECODE_ENTRY( "gfx1", 0, layout_8x8x8, 0x0000, 0x10 ) // [0] Sprites + GFXDECODE_ENTRY( "gfx1", 0, spritelayout, 0x0000, 0x10 ) // [0] Sprites GFXDECODE_ENTRY( "gfx2", 0, layout_16x16x8, 0x1000, 0x10 ) // [1] Background GFXDECODE_ENTRY( "gfx3", 0, layout_16x16x8, 0x2000, 0x10 ) // [2] Rotation GFXDECODE_ENTRY( "gfx4", 0, layout_8x8x8, 0x6000, 0x10 ) // [3] Foreground GFXDECODE_END static GFXDECODE_START( rocknms ) - GFXDECODE_ENTRY( "gfx1", 0, layout_8x8x8, 0x0000, 0x10 ) // [0] Sprites + GFXDECODE_ENTRY( "gfx1", 0, spritelayout, 0x0000, 0x10 ) // [0] Sprites GFXDECODE_ENTRY( "gfx2", 0, layout_16x16x8, 0x1000, 0x10 ) // [1] Background GFXDECODE_ENTRY( "gfx3", 0, layout_16x16x8, 0x2000, 0x10 ) // [2] Rotation GFXDECODE_ENTRY( "gfx4", 0, layout_8x8x8, 0x6000, 0x10 ) // [3] Foreground - GFXDECODE_ENTRY( "gfx5", 0, layout_8x8x8, 0x8000, 0x10 ) // [0] Sprites + GFXDECODE_ENTRY( "gfx5", 0, spritelayout, 0x8000, 0x10 ) // [0] Sprites GFXDECODE_ENTRY( "gfx6", 0, layout_16x16x8, 0x9000, 0x10 ) // [1] Background GFXDECODE_ENTRY( "gfx7", 0, layout_16x16x8, 0xa000, 0x10 ) // [2] Rotation GFXDECODE_ENTRY( "gfx8", 0, layout_8x8x8, 0xe000, 0x10 ) // [3] Foreground diff --git a/src/mame/includes/ms32.h b/src/mame/includes/ms32.h index 65f60fc437f..1f419d3ea4f 100644 --- a/src/mame/includes/ms32.h +++ b/src/mame/includes/ms32.h @@ -11,6 +11,8 @@ extern void decrypt_ms32_bg(running_machine *machine, int addr_xor,int data_xor, extern UINT32 *ms32_roz_ctrl; extern UINT32 *ms32_tx_scroll; extern UINT32 *ms32_bg_scroll; + +/* extern UINT32 *ms32_priram; extern UINT32 *ms32_palram; extern UINT32 *ms32_bgram; @@ -18,9 +20,11 @@ extern UINT32 *ms32_rozram; extern UINT32 *ms32_lineram; extern UINT32 *ms32_spram; extern UINT32 *ms32_txram; +*/ extern UINT32 *ms32_mainram; WRITE32_HANDLER( ms32_brightness_w ); +/* WRITE32_HANDLER( ms32_palram_w ); READ32_HANDLER( ms32_txram_r ); WRITE32_HANDLER( ms32_txram_w ); @@ -32,8 +36,8 @@ READ32_HANDLER( ms32_bgram_r ); WRITE32_HANDLER( ms32_bgram_w ); READ32_HANDLER( ms32_spram_r ); WRITE32_HANDLER( ms32_spram_w ); -READ32_HANDLER( ms32_priram_r ); -WRITE32_HANDLER( ms32_priram_w ); +*/ + WRITE32_HANDLER( ms32_gfxctrl_w ); VIDEO_START( ms32 ); VIDEO_UPDATE( ms32 ); diff --git a/src/mame/includes/tetrisp2.h b/src/mame/includes/tetrisp2.h index 4131f5014b6..ca0131cc19b 100644 --- a/src/mame/includes/tetrisp2.h +++ b/src/mame/includes/tetrisp2.h @@ -9,7 +9,7 @@ extern UINT16 *tetrisp2_vram_bg, *tetrisp2_scroll_bg; extern UINT16 *tetrisp2_vram_fg, *tetrisp2_scroll_fg; extern UINT16 *tetrisp2_vram_rot, *tetrisp2_rotregs; -extern UINT16 *tetrisp2_priority; +extern UINT8 *tetrisp2_priority; extern UINT16 *rocknms_sub_vram_bg, *rocknms_sub_scroll_bg; extern UINT16 *rocknms_sub_vram_fg, *rocknms_sub_scroll_fg; @@ -19,8 +19,9 @@ extern UINT16 *rocknms_sub_priority; WRITE16_HANDLER( tetrisp2_palette_w ); WRITE16_HANDLER( rocknms_sub_palette_w ); -WRITE16_HANDLER( tetrisp2_priority_w ); -WRITE16_HANDLER( rockn_priority_w ); +WRITE8_HANDLER( tetrisp2_priority_w ); +WRITE8_HANDLER( rockn_priority_w ); +READ8_HANDLER( tetrisp2_priority_r ); WRITE16_HANDLER( rocknms_sub_priority_w ); READ16_HANDLER( nndmseal_priority_r ); diff --git a/src/mame/video/ms32.c b/src/mame/video/ms32.c index 41106492bd6..7c471af6131 100644 --- a/src/mame/video/ms32.c +++ b/src/mame/video/ms32.c @@ -15,26 +15,39 @@ priority should be given to #include "driver.h" #include "includes/ms32.h" +bitmap_t* temp_bitmap_tilemaps; +bitmap_t* temp_bitmap_sprites; +bitmap_t* temp_bitmap_sprites_pri; + //UINT32 *ms32_fce00000; UINT32 *ms32_roz_ctrl; UINT32 *ms32_tx_scroll; UINT32 *ms32_bg_scroll; -UINT32 *ms32_priram; -UINT32 *ms32_palram; -UINT32 *ms32_bgram; -UINT32 *ms32_rozram; -UINT32 *ms32_lineram; -UINT32 *ms32_spram; -UINT32 *ms32_txram; +//UINT32 *ms32_priram; +//UINT32 *ms32_palram; +//UINT32 *ms32_rozram; +//UINT32 *ms32_lineram; +//UINT32 *ms32_spram; +//UINT32 *ms32_bgram; +//UINT32 *ms32_txram; UINT32 *ms32_mainram; + +UINT8* ms32_priram_8; +UINT16* ms32_palram_16; +UINT16* ms32_rozram_16; +UINT16 *ms32_lineram_16; +UINT16 *ms32_sprram_16; +UINT16 *ms32_bgram_16; +UINT16 *ms32_txram_16; + // kirarast, tp2m32, and 47pie2 require the sprites in a different order static int ms32_reverse_sprite_order; /********** Tilemaps **********/ -static tilemap *ms32_tx_tilemap, *ms32_roz_tilemap, *ms32_bg_tilemap; +tilemap *ms32_tx_tilemap, *ms32_roz_tilemap, *ms32_bg_tilemap; static int flipscreen; @@ -42,8 +55,8 @@ static TILE_GET_INFO( get_ms32_tx_tile_info ) { int tileno, colour; - tileno = ms32_txram[tile_index *2] & 0x0000ffff; - colour = ms32_txram[tile_index *2+1] & 0x000000f; + tileno = ms32_txram_16[tile_index *2] & 0xffff; + colour = ms32_txram_16[tile_index *2+1] & 0x000f; SET_TILE_INFO(3,tileno,colour,0); } @@ -52,8 +65,8 @@ static TILE_GET_INFO( get_ms32_roz_tile_info ) { int tileno,colour; - tileno = ms32_rozram[tile_index *2] & 0x0000ffff; - colour = ms32_rozram[tile_index *2+1] & 0x000000f; + tileno = ms32_rozram_16[tile_index *2] & 0xffff; + colour = ms32_rozram_16[tile_index *2+1] & 0x000f; SET_TILE_INFO(1,tileno,colour,0); } @@ -62,8 +75,8 @@ static TILE_GET_INFO( get_ms32_bg_tile_info ) { int tileno,colour; - tileno = ms32_bgram[tile_index *2] & 0x0000ffff; - colour = ms32_bgram[tile_index *2+1] & 0x000000f; + tileno = ms32_bgram_16[tile_index *2] & 0xffff; + colour = ms32_bgram_16[tile_index *2+1] & 0x000f; SET_TILE_INFO(2,tileno,colour,0); } @@ -73,10 +86,28 @@ static int brt_r,brt_g,brt_b; VIDEO_START( ms32 ) { + int width = video_screen_get_width(machine->primary_screen); + int height = video_screen_get_height(machine->primary_screen); + + ms32_priram_8 = auto_alloc_array(machine, UINT8, 0x2000); + ms32_palram_16 = auto_alloc_array(machine, UINT16, 0x20000); + ms32_rozram_16 = auto_alloc_array(machine, UINT16, 0x10000); + ms32_lineram_16 = auto_alloc_array(machine, UINT16, 0x1000); + ms32_sprram_16 = auto_alloc_array(machine, UINT16, 0x20000); + ms32_bgram_16 = auto_alloc_array(machine, UINT16, 0x4000); + ms32_txram_16 = auto_alloc_array(machine, UINT16, 0x4000); + ms32_tx_tilemap = tilemap_create(machine, get_ms32_tx_tile_info,tilemap_scan_rows,8, 8,64,64); ms32_bg_tilemap = tilemap_create(machine, get_ms32_bg_tile_info,tilemap_scan_rows,16,16,64,64); ms32_roz_tilemap = tilemap_create(machine, get_ms32_roz_tile_info,tilemap_scan_rows,16,16,128,128); + + /* set up tile layers */ + temp_bitmap_tilemaps = auto_bitmap_alloc(machine, width, height, BITMAP_FORMAT_INDEXED16); + temp_bitmap_sprites = auto_bitmap_alloc(machine, width, height, BITMAP_FORMAT_INDEXED16); + temp_bitmap_sprites_pri = auto_bitmap_alloc(machine, width, height, BITMAP_FORMAT_INDEXED16); // not actually being used for rendering, we embed pri info in the raw colour bitmap + + tilemap_set_transparent_pen(ms32_tx_tilemap,0); tilemap_set_transparent_pen(ms32_bg_tilemap,0); tilemap_set_transparent_pen(ms32_roz_tilemap,0); @@ -109,15 +140,15 @@ static void update_color(running_machine *machine, int color) */ if (~color & 0x4000) { - r = ((ms32_palram[color*2] & 0xff00) >>8 ) * brt_r / 0x100; - g = ((ms32_palram[color*2] & 0x00ff) >>0 ) * brt_g / 0x100; - b = ((ms32_palram[color*2+1] & 0x00ff) >>0 ) * brt_b / 0x100; + r = ((ms32_palram_16[color*2] & 0xff00) >>8 ) * brt_r / 0x100; + g = ((ms32_palram_16[color*2] & 0x00ff) >>0 ) * brt_g / 0x100; + b = ((ms32_palram_16[color*2+1] & 0x00ff) >>0 ) * brt_b / 0x100; } else { - r = ((ms32_palram[color*2] & 0xff00) >>8 ); - g = ((ms32_palram[color*2] & 0x00ff) >>0 ); - b = ((ms32_palram[color*2+1] & 0x00ff) >>0 ); + r = ((ms32_palram_16[color*2] & 0xff00) >>8 ); + g = ((ms32_palram_16[color*2] & 0x00ff) >>0 ); + b = ((ms32_palram_16[color*2+1] & 0x00ff) >>0 ); } palette_set_color(machine,color,MAKE_RGB(r,g,b)); @@ -131,7 +162,7 @@ WRITE32_HANDLER( ms32_brightness_w ) if (brt[offset] != oldword) { int bank = ((offset & 2) >> 1) * 0x4000; - int i; + //int i; if (bank == 0) { @@ -139,85 +170,18 @@ WRITE32_HANDLER( ms32_brightness_w ) brt_g = 0x100 - ((brt[0] & 0x00ff) >> 0); brt_b = 0x100 - ((brt[1] & 0x00ff) >> 0); - for (i = 0;i < 0x3000;i++) // colors 0x3000-0x3fff are not used - update_color(space->machine, i); + // for (i = 0;i < 0x3000;i++) // colors 0x3000-0x3fff are not used + // update_color(space->machine, i); } } //popmessage("%04x %04x %04x %04x",brt[0],brt[1],brt[2],brt[3]); } -WRITE32_HANDLER( ms32_palram_w ) -{ - COMBINE_DATA(&ms32_palram[offset]); - - update_color(space->machine, offset/2); -} -READ32_HANDLER( ms32_txram_r ) -{ - return ms32_txram[offset]; -} -WRITE32_HANDLER( ms32_txram_w ) -{ - COMBINE_DATA(&ms32_txram[offset]); - tilemap_mark_tile_dirty(ms32_tx_tilemap,offset/2); -} - -READ32_HANDLER( ms32_rozram_r ) -{ - return ms32_rozram[offset]; -} - -WRITE32_HANDLER( ms32_rozram_w ) -{ - COMBINE_DATA(&ms32_rozram[offset]); - tilemap_mark_tile_dirty(ms32_roz_tilemap,offset/2); -} - -READ32_HANDLER( ms32_lineram_r ) -{ - return ms32_lineram[offset]; -} - -WRITE32_HANDLER( ms32_lineram_w ) -{ - COMBINE_DATA(&ms32_lineram[offset]); -} - -READ32_HANDLER( ms32_bgram_r ) -{ - return ms32_bgram[offset]; -} - -WRITE32_HANDLER( ms32_bgram_w ) -{ - COMBINE_DATA(&ms32_bgram[offset]); - tilemap_mark_tile_dirty(ms32_bg_tilemap,offset/2); -} - -READ32_HANDLER( ms32_spram_r ) -{ - return ms32_spram[offset]; -} - -WRITE32_HANDLER( ms32_spram_w ) -{ - COMBINE_DATA(&ms32_spram[offset]); -} - -READ32_HANDLER( ms32_priram_r ) -{ - return ms32_priram[offset]; -} - -WRITE32_HANDLER( ms32_priram_w ) -{ - COMBINE_DATA(&ms32_priram[offset]); -} WRITE32_HANDLER( ms32_gfxctrl_w ) { @@ -239,138 +203,10 @@ WRITE32_HANDLER( ms32_gfxctrl_w ) /* SPRITES based on tetrisp2 for now, readd priority bits later */ - -static void draw_sprites(running_machine *machine, bitmap_t *bitmap, const rectangle *cliprect, UINT32 *sprram_top, size_t sprram_size) -{ -/*************************************************************************** +/* now using function in tetrisp2.c */ +void tetrisp2_draw_sprites(running_machine *machine, bitmap_t *bitmap, bitmap_t *bitmap_pri, const rectangle *cliprect, UINT8* priram, UINT16 *sprram_top, size_t sprram_size, int gfxnum, int reverseorder, int flip, int allowzoom); - Sprites Drawing - - Offset: Bits: Meaning: - - 0.w fedc ba98 ---- ---- - ---- ---- 7654 ---- Priority - ---- ---- ---- 3--- - ---- ---- ---- -2-- Draw this sprite - ---- ---- ---- --1- Flip Y - ---- ---- ---- ---0 Flip X - - 1.w fedc ba98 ---- ---- Tile's Y position in the tile page (*) - ---- ---- 7654 3210 Tile's X position in the tile page (*) - - 2.w fedc ---- ---- ---- Color - ---- ba98 7654 3210 Tile Page (32x32 tiles = 256x256 pixels each) - - 3.w fedc ba98 ---- ---- Y Size - 1 (*) - ---- ---- 7654 3210 X Size - 1 (*) - - 4.w fedc ba-- ---- ---- - ---- --98 7654 3210 Y (Signed) - - 5.w fedc b--- ---- ---- - ---- -a98 7654 3210 X (Signed) - - 6.w fedc ba98 7654 3210 Zoom Y - - 7.w fedc ba98 7654 3210 Zoom X - -(*) 1 pixel granularity - -***************************************************************************/ - - int tx, ty, sx, sy, flipx, flipy; - int xsize, ysize, xzoom, yzoom; - int code, attr, color, size, pri, pri_mask; - gfx_element *gfx = machine->gfx[0]; - - UINT32 *source = sprram_top; - const UINT32 *finish = sprram_top + (sprram_size - 0x20) / 4; - - - if (ms32_reverse_sprite_order == 1) - { - source = sprram_top + (sprram_size - 0x20) / 4; - finish = sprram_top; - } - - - for (;ms32_reverse_sprite_order ? (source>=finish) : (source> 4)&0xf; - - code = source[ 1 ]; - color = source[ 2 ]; - - tx = (code >> 0) & 0xff; - ty = (code >> 8) & 0xff; - - code = (color & 0x0fff); - - color = (color >> 12) & 0xf; - - size = source[ 3 ]; - - xsize = ((size >> 0) & 0xff) + 1; - ysize = ((size >> 8) & 0xff) + 1; - - sy = source[ 4 ]; - sx = source[ 5 ]; - - sx = (sx & 0x3ff) - (sx & 0x400); - sy = (sy & 0x1ff) - (sy & 0x200); - - xzoom = (source[ 6 ]&0xffff); - yzoom = (source[ 7 ]&0xffff); - - if (!yzoom || !xzoom) continue; - - yzoom = 0x1000000/yzoom; - xzoom = 0x1000000/xzoom; - - // there are surely also shadows (see gametngk) but how they're enabled we don't know - - if (flipscreen) - { - sx = 320 - ((xsize*xzoom)>>16) - sx; - sy = 224 - ((ysize*yzoom)>>16) - sy; - flipx = !flipx; - flipy = !flipy; - } - -#if 0 -if (input_code_pressed(machine, KEYCODE_A) && (pri & 8)) color = rand(); -if (input_code_pressed(machine, KEYCODE_S) && (pri & 4)) color = rand(); -if (input_code_pressed(machine, KEYCODE_D) && (pri & 2)) color = rand(); -if (input_code_pressed(machine, KEYCODE_F) && (pri & 1)) color = rand(); -#endif - - /* TODO: priority handling is completely wrong, but better than nothing */ - if (pri == 0x0) - pri_mask = 0x00; - else if (pri <= 0xd) - pri_mask = 0xf0; - else if (pri <= 0xe) - pri_mask = 0xfc; - else - pri_mask = 0xfe; - - gfx_element_set_source_clip(gfx, tx, xsize, ty, ysize); - pdrawgfxzoom_transpen(bitmap, cliprect, gfx, - code, - color, - flipx, flipy, - sx,sy, - xzoom, yzoom, machine->priority_bitmap,pri_mask, 0); - } /* end sprite loop */ -} @@ -391,7 +227,7 @@ static void draw_roz(bitmap_t *bitmap, const rectangle *cliprect,int priority) while (y <= maxy) { - UINT32 *lineaddr = ms32_lineram + 8 * (y & 0xff); + UINT16 *lineaddr = ms32_lineram_16 + 8 * (y & 0xff); int start2x = (lineaddr[0x00/4] & 0xffff) | ((lineaddr[0x04/4] & 3) << 16); int start2y = (lineaddr[0x08/4] & 0xffff) | ((lineaddr[0x0c/4] & 3) << 16); @@ -459,6 +295,9 @@ static void draw_roz(bitmap_t *bitmap, const rectangle *cliprect,int priority) VIDEO_UPDATE( ms32 ) { int scrollx,scrolly; + int asc_pri; + int scr_pri; + int rot_pri; /* TODO: registers 0x04/4 and 0x10/4 are used too; the most interesting case is gametngk, where they are *usually*, but not always, copies of 0x00/4 @@ -468,6 +307,11 @@ VIDEO_UPDATE( ms32 ) The two registers might be somewhat related to the width and height of the tilemaps, but there's something that just doesn't fit. */ + int i; + + for (i = 0;i < 0x10000;i++) // colors 0x3000-0x3fff are not used + update_color(screen->machine, i); + scrollx = ms32_tx_scroll[0x00/4] + ms32_tx_scroll[0x08/4] + 0x18; scrolly = ms32_tx_scroll[0x0c/4] + ms32_tx_scroll[0x14/4]; tilemap_set_scrollx(ms32_tx_tilemap, 0, scrollx); @@ -481,26 +325,313 @@ VIDEO_UPDATE( ms32 ) bitmap_fill(screen->machine->priority_bitmap,cliprect,0); + + /* TODO: 0 is correct for gametngk, but break f1superb scrolling grid (text at top and bottom of the screen becomes black on black) */ - bitmap_fill(bitmap,cliprect,0); /* bg color */ + bitmap_fill(temp_bitmap_tilemaps,cliprect,0); /* bg color */ + + /* clear our sprite bitmaps */ + bitmap_fill(temp_bitmap_sprites,cliprect,0); + bitmap_fill(temp_bitmap_sprites_pri,cliprect,0); + + tetrisp2_draw_sprites(screen->machine, temp_bitmap_sprites, temp_bitmap_sprites_pri, cliprect, NULL, ms32_sprram_16, 0x20000, 0, ms32_reverse_sprite_order, 0, 1 ); + + - /* priority hack, we really need to figure out what priority ram is I think */ - if (!strcmp(screen->machine->gamedrv->name,"hayaosi3")) - { - tilemap_draw(bitmap,cliprect,ms32_bg_tilemap,0,1); - tilemap_draw(bitmap,cliprect,ms32_tx_tilemap,0,4); - draw_roz(bitmap,cliprect,4); // this question text needs to appear over the sprites - draw_sprites(screen->machine,bitmap,cliprect, ms32_spram, 0x40000); + asc_pri = scr_pri = rot_pri = 0; - } + if((ms32_priram_8[0x2b00 / 2] & 0x00ff) == 0x0034) + asc_pri++; else + rot_pri++; + + if((ms32_priram_8[0x2e00 / 2] & 0x00ff) == 0x0034) + asc_pri++; + else + scr_pri++; + + if((ms32_priram_8[0x3a00 / 2] & 0x00ff) == 0x000c) + scr_pri++; + else + rot_pri++; + + if (rot_pri == 0) + draw_roz(temp_bitmap_tilemaps,cliprect, 1 << 1); + else if (scr_pri == 0) + tilemap_draw(temp_bitmap_tilemaps,cliprect, ms32_bg_tilemap, 0, 1 << 0); + else if (asc_pri == 0) + tilemap_draw(temp_bitmap_tilemaps,cliprect, ms32_tx_tilemap, 0, 1 << 2); + + if (rot_pri == 1) + draw_roz(temp_bitmap_tilemaps,cliprect, 1 << 1); + else if (scr_pri == 1) + tilemap_draw(temp_bitmap_tilemaps,cliprect, ms32_bg_tilemap, 0, 1 << 0); + else if (asc_pri == 1) + tilemap_draw(temp_bitmap_tilemaps,cliprect, ms32_tx_tilemap, 0, 1 << 2); + + if (rot_pri == 2) + draw_roz(temp_bitmap_tilemaps,cliprect, 1 << 1); + else if (scr_pri == 2) + tilemap_draw(temp_bitmap_tilemaps,cliprect, ms32_bg_tilemap, 0, 1 << 0); + else if (asc_pri == 2) + tilemap_draw(temp_bitmap_tilemaps,cliprect, ms32_tx_tilemap, 0, 1 << 2); + + /* MIX it! */ + /* this mixing isn't 100% accurate, it should be using ALL the data in + the priority ram, probably for per-pixel / pen mixing, or more levels + than are supported here.. I don't know, it will need hw tests I think */ { - tilemap_draw(bitmap,cliprect,ms32_bg_tilemap,0,1); - draw_roz(bitmap,cliprect,2); - tilemap_draw(bitmap,cliprect,ms32_tx_tilemap,0,4); - draw_sprites(screen->machine,bitmap,cliprect, ms32_spram, 0x40000); + int xx, yy; + int width = video_screen_get_width(screen); + int height = video_screen_get_height(screen); + const pen_t *paldata = screen->machine->pens; + + UINT16* srcptr_tile; + UINT8* srcptr_tilepri; + UINT16* srcptr_spri; + //UINT8* srcptr_spripri; + + UINT32* dstptr_bitmap; + + bitmap_fill(bitmap,cliprect,0); + + for (yy=0;yymachine->priority_bitmap, yy, 0); + srcptr_spri = BITMAP_ADDR16(temp_bitmap_sprites, yy, 0); + //srcptr_spripri = BITMAP_ADDR8(temp_bitmap_sprites_pri, yy, 0); + dstptr_bitmap = BITMAP_ADDR32(bitmap, yy, 0); + for (xx=0;xx> 8); + int primask = 0; + + // get sprite priority value back out of bitmap/colour data (this is done in draw_sprite for standalone hw) + if (ms32_priram_8[(spritepri | 0x0a00 | 0x1500) / 2] & 0x38) primask |= 1 << 0; + if (ms32_priram_8[(spritepri | 0x0a00 | 0x1400) / 2] & 0x38) primask |= 1 << 1; + if (ms32_priram_8[(spritepri | 0x0a00 | 0x1100) / 2] & 0x38) primask |= 1 << 2; + if (ms32_priram_8[(spritepri | 0x0a00 | 0x1000) / 2] & 0x38) primask |= 1 << 3; + if (ms32_priram_8[(spritepri | 0x0a00 | 0x0500) / 2] & 0x38) primask |= 1 << 4; + if (ms32_priram_8[(spritepri | 0x0a00 | 0x0400) / 2] & 0x38) primask |= 1 << 5; + if (ms32_priram_8[(spritepri | 0x0a00 | 0x0100) / 2] & 0x38) primask |= 1 << 6; + if (ms32_priram_8[(spritepri | 0x0a00 | 0x0000) / 2] & 0x38) primask |= 1 << 7; + + + if (primask == 0x00) + { + + if (src_tilepri==0x00) + { + if (spridat & 0xff) + dstptr_bitmap[xx] = paldata[spridat]; // best bout boxing title + else + dstptr_bitmap[xx] = paldata[src_tile]; + } + else if (src_tilepri==0x01) + { + if (spridat & 0xff) + dstptr_bitmap[xx] = paldata[spridat]; // best bout boxing title + else + dstptr_bitmap[xx] = paldata[src_tile]; + } + else if (src_tilepri==0x02) + { + if (spridat & 0xff) + dstptr_bitmap[xx] = paldata[spridat]; // best bout boxing + else + dstptr_bitmap[xx] = paldata[src_tile]; + } + else if (src_tilepri==0x03) + { + if (spridat & 0xff) + dstptr_bitmap[xx] = paldata[spridat]; // best bout boxing + else + dstptr_bitmap[xx] = paldata[src_tile]; + } + else if (src_tilepri==0x04) + { + if (spridat & 0xff) + dstptr_bitmap[xx] = paldata[spridat]; + else + dstptr_bitmap[xx] = paldata[src_tile]; + } + else if (src_tilepri==0x05) + { + if (spridat & 0xff) + dstptr_bitmap[xx] = paldata[spridat]; + else + dstptr_bitmap[xx] = paldata[src_tile]; + } + else if (src_tilepri==0x06) + { + if (spridat & 0xff) + dstptr_bitmap[xx] = paldata[spridat]; + else + dstptr_bitmap[xx] = paldata[src_tile]; + } + else if (src_tilepri==0x07) + { + if (spridat & 0xff) + dstptr_bitmap[xx] = paldata[spridat]; // desert war radar? + else + dstptr_bitmap[xx] = paldata[src_tile]; + } + + + } + else if (primask == 0xc0) + { + dstptr_bitmap[xx] = paldata[mame_rand(screen->machine)&0xfff]; + } + else if (primask == 0xf0) + { +// dstptr_bitmap[xx] = paldata[spridat]; + if (src_tilepri==0x00) + { + if (spridat & 0xff) + dstptr_bitmap[xx] = paldata[spridat]; // clouds at top gametngk intro + else + dstptr_bitmap[xx] = paldata[src_tile]; + } + else if (src_tilepri==0x01) + { + if (spridat & 0xff) + dstptr_bitmap[xx] = paldata[spridat]; // clouds gametngk intro + else + dstptr_bitmap[xx] = paldata[src_tile]; + } + else if (src_tilepri==0x02) + { + if (spridat & 0xff) + dstptr_bitmap[xx] = paldata[spridat]; // mode select gametngk + else + dstptr_bitmap[xx] = paldata[src_tile]; + } + else if (src_tilepri==0x03) + { + if (spridat & 0xff) + dstptr_bitmap[xx] = paldata[spridat]; // title gametngk + else + dstptr_bitmap[xx] = paldata[src_tile]; + } + else if (src_tilepri==0x04) + { + dstptr_bitmap[xx] = paldata[src_tile]; // insert coin text on girl gametngk intro + } + else if (src_tilepri==0x05) + { + dstptr_bitmap[xx] = paldata[src_tile]; // insert coin gametngk intro + } + else if (src_tilepri==0x06) + { + dstptr_bitmap[xx] = paldata[src_tile]; // insert coin gametngk intro + } + else if (src_tilepri==0x07) + { + dstptr_bitmap[xx] = paldata[src_tile]; // insert coin gametngk intro + } + } + else if (primask == 0xfc) + { + if (src_tilepri==0x00) + { + if (spridat & 0xff) + dstptr_bitmap[xx] = paldata[spridat]; // tetrisp intro text + else + dstptr_bitmap[xx] = paldata[src_tile]; + } + else if (src_tilepri==0x01) + { + if (spridat & 0xff) + dstptr_bitmap[xx] = paldata[spridat]; // tetrisp intro text + else + dstptr_bitmap[xx] = paldata[src_tile]; + } + else if (src_tilepri==0x02) + { + dstptr_bitmap[xx] = paldata[src_tile]; // tetrisp story + } + else if (src_tilepri==0x03) + { + dstptr_bitmap[xx] = paldata[src_tile]; // tetrisp fader to game after story + } + else if (src_tilepri==0x04) + { + dstptr_bitmap[xx] = paldata[src_tile]; // credit text tetrisp mode select + } + else if (src_tilepri==0x05) + { + dstptr_bitmap[xx] = paldata[src_tile]; // credit text tetrisp intro + } + else if (src_tilepri==0x06) + { + //dstptr_bitmap[xx] = paldata[mame_rand(screen->machine)&0xfff]; + dstptr_bitmap[xx] = paldata[src_tile]; // assumed + } + else if (src_tilepri==0x07) + { + //dstptr_bitmap[xx] = paldata[mame_rand(screen->machine)&0xfff]; + dstptr_bitmap[xx] = paldata[src_tile]; // assumed + } + } + else if (primask == 0xfe) + { + if (src_tilepri==0x00) + { + if (spridat & 0xff) + dstptr_bitmap[xx] = paldata[spridat]; // screens in gametngk intro + else + dstptr_bitmap[xx] = paldata[src_tile]; + } + else if (src_tilepri==0x01) + { + dstptr_bitmap[xx] = alpha_blend_r32( paldata[src_tile], 0x00000000, 128); // shadow, gametngk title + } + else if (src_tilepri==0x02) + { + dstptr_bitmap[xx] = alpha_blend_r32( paldata[src_tile], 0x00000000, 128); // shadow, gametngk mode select + } + else if (src_tilepri==0x03) + { + dstptr_bitmap[xx] = alpha_blend_r32( paldata[src_tile], 0x00000000, 128); // shadow, gametngk title + } + else if (src_tilepri==0x04) + { + dstptr_bitmap[xx] = paldata[src_tile]; // credit text gametngk intro + } + else if (src_tilepri==0x05) + { + dstptr_bitmap[xx] = paldata[src_tile]; // credit text near shadow, gametngk title + } + else if (src_tilepri==0x06) + { + dstptr_bitmap[xx] = paldata[src_tile]; // credit gametngk highscores + } + else if (src_tilepri==0x07) + { + dstptr_bitmap[xx] = paldata[src_tile]; // assumed + } + } + + else + { + fatalerror("unhandled priority type %02x\n",primask); + } + + + + } + + } + } diff --git a/src/mame/video/tetrisp2.c b/src/mame/video/tetrisp2.c index babe1fe710d..fa1ea0a4dfa 100644 --- a/src/mame/video/tetrisp2.c +++ b/src/mame/video/tetrisp2.c @@ -5,15 +5,6 @@ driver by Luca Elia (l.elia@tin.it) -Note: if MAME_DEBUG is defined, pressing Z with: - - Q shows the background - W shows the foreground - A shows the sprites - - Keys can be used together! - - [ 2 Scrolling Layers ] The Background is a 64 x 64 Tilemap with 16 x 16 x 8 tiles (1024 x 1024). @@ -34,7 +25,8 @@ To Do: - There is a 3rd unimplemented layer capable of rotation (not used by the game, can be tested in service mode). -- Priority RAM is not taken into account. +- Priority RAM is not properly taken into account. +- Can the Tetris Plus 2 sprites zoom, or is this an MS32 only feature? ***************************************************************************/ @@ -48,7 +40,7 @@ UINT16 *tetrisp2_vram_bg, *tetrisp2_scroll_bg; UINT16 *tetrisp2_vram_fg, *tetrisp2_scroll_fg; UINT16 *tetrisp2_vram_rot, *tetrisp2_rotregs; -UINT16 *tetrisp2_priority; +UINT8 *tetrisp2_priority; UINT16 *rocknms_sub_vram_bg, *rocknms_sub_scroll_bg; UINT16 *rocknms_sub_vram_fg, *rocknms_sub_scroll_fg; @@ -91,9 +83,9 @@ WRITE16_HANDLER( rocknms_sub_palette_w ) ***************************************************************************/ -WRITE16_HANDLER( tetrisp2_priority_w ) +WRITE8_HANDLER( tetrisp2_priority_w ) { - if (ACCESSING_BITS_8_15) + //if (ACCESSING_BITS_8_15) { data |= ((data & 0xff00) >> 8); tetrisp2_priority[offset] = data; @@ -101,9 +93,9 @@ WRITE16_HANDLER( tetrisp2_priority_w ) } -WRITE16_HANDLER( rockn_priority_w ) +WRITE8_HANDLER( rockn_priority_w ) { - if (ACCESSING_BITS_8_15) + //if (ACCESSING_BITS_8_15) { tetrisp2_priority[offset] = data; } @@ -122,6 +114,10 @@ READ16_HANDLER( nndmseal_priority_r ) return tetrisp2_priority[offset] | 0xff00; } +READ8_HANDLER( tetrisp2_priority_r ) +{ + return tetrisp2_priority[offset]; +} /*************************************************************************** @@ -256,6 +252,7 @@ WRITE16_HANDLER( rocknms_sub_vram_rot_w ) +extern void ms32_rearrange_sprites(running_machine *machine, const char *region); VIDEO_START( tetrisp2 ) { @@ -276,6 +273,10 @@ VIDEO_START( tetrisp2 ) tilemap_set_transparent_pen(tilemap_bg,0); tilemap_set_transparent_pen(tilemap_fg,0); tilemap_set_transparent_pen(tilemap_rot,0); + + // should be smaller and mirrored like m32 I guess + tetrisp2_priority = auto_alloc_array(machine, UINT8, 0x40000); + ms32_rearrange_sprites(machine, "gfx1"); } VIDEO_START( nndmseal ) @@ -303,6 +304,10 @@ VIDEO_START( rockntread ) tilemap_set_transparent_pen(tilemap_bg, 0); tilemap_set_transparent_pen(tilemap_fg, 0); tilemap_set_transparent_pen(tilemap_rot, 0); + + // should be smaller and mirrored like m32 I guess + tetrisp2_priority = auto_alloc_array(machine, UINT8, 0x40000); + ms32_rearrange_sprites(machine, "gfx1"); } @@ -325,6 +330,8 @@ VIDEO_START( rocknms ) tilemap_set_transparent_pen(tilemap_sub_bg, 0); tilemap_set_transparent_pen(tilemap_sub_fg, 0); tilemap_set_transparent_pen(tilemap_sub_rot, 0); + + ms32_rearrange_sprites(machine, "gfx5"); } @@ -367,34 +374,42 @@ VIDEO_START( rocknms ) ***************************************************************************/ -static void draw_sprites(running_machine *machine, bitmap_t *bitmap, const rectangle *cliprect, UINT16 *sprram_top, size_t sprram_size, int gfxnum) +/* this is also used by ms32.c */ +/* sprites should be able to create shadows too, how? + -- it appears that sprites which should be shadows are often rendered *UNDER* the tilemaps, maybe related? +*/ +void tetrisp2_draw_sprites(running_machine *machine, bitmap_t *bitmap, bitmap_t *bitmap_pri, const rectangle *cliprect, UINT8* priram, UINT16 *sprram_top, size_t sprram_size, int gfxnum, int reverseorder, int flip, int allowzoom) { - int x, y, tx, ty, sx, sy, flipx, flipy; - int xsize, ysize, xnum, ynum; - int xstart, ystart, xend, yend, xinc, yinc; + int tx, ty, sx, sy, flipx, flipy; + int xsize, ysize; int code, attr, color, size; int flipscreen; + int pri; + int xzoom, yzoom; UINT32 primask; - UINT16 *priority_ram; - - int min_x = cliprect->min_x; - int max_x = cliprect->max_x; - int min_y = cliprect->min_y; - int max_y = cliprect->max_y; + UINT8 *priority_ram; + gfx_element *gfx = machine->gfx[gfxnum]; UINT16 *source = sprram_top; - const UINT16 *finish = sprram_top + (sprram_size - 0x10) / 2; + UINT16 *finish = sprram_top + (sprram_size - 0x10) / 2; + + flipscreen = flip; - priority_ram = tetrisp2_priority; - - flipscreen = (tetrisp2_systemregs[0x00] & 0x02); - - for (; source <= finish; source += 0x10/2 ) + if (reverseorder == 1) { - rectangle clip; + source = sprram_top + (sprram_size - 0x10) / 2; + finish = sprram_top; + } + priority_ram = priram; + + + for (;reverseorder ? (source>=finish) : (source> 0) & 0xff; ty = (code >> 8) & 0xff; - code = (tx / 8) + - (ty / 8) * (0x100/8) + - (color & 0x7f) * (0x100/8) * (0x100/8); + code = (color & 0x0fff); color = (color >> 12) & 0xf; @@ -417,72 +430,67 @@ static void draw_sprites(running_machine *machine, bitmap_t *bitmap, const recta xsize = ((size >> 0) & 0xff) + 1; ysize = ((size >> 8) & 0xff) + 1; - xnum = ( ((tx + xsize) & ~7) + (((tx + xsize) & 7) ? 8 : 0) - (tx & ~7) ) / 8; - ynum = ( ((ty + ysize) & ~7) + (((ty + ysize) & 7) ? 8 : 0) - (ty & ~7) ) / 8; - sy = source[ 4 ]; sx = source[ 5 ]; sx = (sx & 0x3ff) - (sx & 0x400); sy = (sy & 0x1ff) - (sy & 0x200); - /* Flip Screen */ - if (flipscreen) + xzoom = (source[ 6 ]&0xffff); + yzoom = (source[ 7 ]&0xffff); + + // tetrisp2 hardware doesn't work with zoom? + if (allowzoom) { - sx = max_x + 1 - sx - xsize; flipx = !flipx; - sy = max_y + 1 - sy - ysize; flipy = !flipy; + if (!yzoom || !xzoom) + continue; + + yzoom = 0x1000000/yzoom; + xzoom = 0x1000000/xzoom; } - - /* Clip the sprite if its width or height is not an integer - multiple of 8 pixels (1 tile) */ - - clip.min_x = sx; - clip.max_x = sx + xsize - 1; - clip.min_y = sy; - clip.max_y = sy + ysize - 1; - - if (clip.min_x > max_x) continue; - if (clip.max_x < min_x) continue; - - if (clip.min_y > max_y) continue; - if (clip.max_y < min_y) continue; - - if (clip.min_x < min_x) clip.min_x = min_x; - if (clip.max_x > max_x) clip.max_x = max_x; - - if (clip.min_y < min_y) clip.min_y = min_y; - if (clip.max_y > max_y) clip.max_y = max_y; - - if (flipx) { xstart = xnum-1; xend = -1; xinc = -1; sx -= xnum*8 - xsize - (tx & 7); } - else { xstart = 0; xend = xnum; xinc = +1; sx -= tx & 7; } - - if (flipy) { ystart = ynum-1; yend = -1; yinc = -1; sy -= ynum*8 - ysize - (ty & 7); } - else { ystart = 0; yend = ynum; yinc = +1; sy -= ty & 7; } - - primask = 0; - if (priority_ram[((attr & 0x00f0) | 0x0a00 | 0x1500) / 2] & 0x38) primask |= 1 << 0; - if (priority_ram[((attr & 0x00f0) | 0x0a00 | 0x1400) / 2] & 0x38) primask |= 1 << 1; - if (priority_ram[((attr & 0x00f0) | 0x0a00 | 0x1100) / 2] & 0x38) primask |= 1 << 2; - if (priority_ram[((attr & 0x00f0) | 0x0a00 | 0x1000) / 2] & 0x38) primask |= 1 << 3; - if (priority_ram[((attr & 0x00f0) | 0x0a00 | 0x0500) / 2] & 0x38) primask |= 1 << 4; - if (priority_ram[((attr & 0x00f0) | 0x0a00 | 0x0400) / 2] & 0x38) primask |= 1 << 5; - if (priority_ram[((attr & 0x00f0) | 0x0a00 | 0x0100) / 2] & 0x38) primask |= 1 << 6; - if (priority_ram[((attr & 0x00f0) | 0x0a00 | 0x0000) / 2] & 0x38) primask |= 1 << 7; - - for (y = ystart; y != yend; y += yinc) + else { - for (x = xstart; x != xend; x += xinc) - { - pdrawgfx_transpen(bitmap, &clip, - machine->gfx[gfxnum], - code++, - color, - flipx, flipy, - sx + x * 8, sy + y * 8, - machine->priority_bitmap, primask, 0); - } - code += (0x100/8) - xnum; + xzoom = 0x10000; + yzoom = 0x10000; } + + + gfx_element_set_source_clip(gfx, tx, xsize, ty, ysize); + + if (priority_ram == NULL) + { + // passes the priority as the upper bits of the colour + // for post-processing in mixer instead + pdrawgfxzoom_transpen_raw(bitmap, cliprect, gfx, + code, + color<<8 | pri<<8, + flipx, flipy, + sx,sy, + xzoom, yzoom, bitmap_pri,0, 0); + } + else + { + primask = 0; + if (priority_ram[(pri | 0x0a00 | 0x1500) / 2] & 0x38) primask |= 1 << 0; + if (priority_ram[(pri | 0x0a00 | 0x1400) / 2] & 0x38) primask |= 1 << 1; + if (priority_ram[(pri | 0x0a00 | 0x1100) / 2] & 0x38) primask |= 1 << 2; + if (priority_ram[(pri | 0x0a00 | 0x1000) / 2] & 0x38) primask |= 1 << 3; + if (priority_ram[(pri | 0x0a00 | 0x0500) / 2] & 0x38) primask |= 1 << 4; + if (priority_ram[(pri | 0x0a00 | 0x0400) / 2] & 0x38) primask |= 1 << 5; + if (priority_ram[(pri | 0x0a00 | 0x0100) / 2] & 0x38) primask |= 1 << 6; + if (priority_ram[(pri | 0x0a00 | 0x0000) / 2] & 0x38) primask |= 1 << 7; + + + pdrawgfxzoom_transpen(bitmap, cliprect, gfx, + code, + color, + flipx, flipy, + sx,sy, + xzoom, yzoom, bitmap_pri,primask, 0); + + } + + } /* end sprite loop */ } @@ -575,7 +583,7 @@ VIDEO_UPDATE( tetrisp2 ) else if (asc_pri == 2) tilemap_draw(bitmap,cliprect, tilemap_fg, 0, 1 << 2); - draw_sprites(screen->machine, bitmap,cliprect, spriteram16, spriteram_size, 0); + tetrisp2_draw_sprites(screen->machine, bitmap,screen->machine->priority_bitmap, cliprect, tetrisp2_priority, spriteram16, spriteram_size, 0, 0, (tetrisp2_systemregs[0x00] & 0x02), 0); return 0; } @@ -659,7 +667,7 @@ VIDEO_UPDATE( rockntread ) else if (asc_pri == 2) tilemap_draw(bitmap,cliprect, tilemap_fg, 0, 1 << 2); - draw_sprites(screen->machine, bitmap,cliprect, spriteram16, spriteram_size, 0); + tetrisp2_draw_sprites(screen->machine, bitmap,screen->machine->priority_bitmap,cliprect, tetrisp2_priority, spriteram16, spriteram_size, 0, 0, (tetrisp2_systemregs[0x00] & 0x02), 0); return 0; } @@ -726,7 +734,7 @@ VIDEO_UPDATE( rocknms ) else if (asc_pri == 2) tilemap_draw(bitmap,cliprect, tilemap_sub_fg, 0, 1 << 2); - draw_sprites(screen->machine, bitmap,cliprect, spriteram16_2, spriteram_2_size, 4); + tetrisp2_draw_sprites(screen->machine, bitmap,screen->machine->priority_bitmap,cliprect, tetrisp2_priority, spriteram16_2, spriteram_2_size, 4, 0, (tetrisp2_systemregs[0x00] & 0x02), 0); } else if (screen == right_screen) /* game screen */ { @@ -779,7 +787,7 @@ VIDEO_UPDATE( rocknms ) else if (asc_pri == 2) tilemap_draw(bitmap,cliprect, tilemap_fg, 0, 1 << 2); - draw_sprites(screen->machine, bitmap,cliprect, spriteram16, spriteram_size, 0); + tetrisp2_draw_sprites(screen->machine, bitmap,screen->machine->priority_bitmap,cliprect, tetrisp2_priority, spriteram16, spriteram_size, 0, 0, (tetrisp2_systemregs[0x00] & 0x02), 0); } return 0;