Jaleco Mega System 32 update: [David Haywood]

* Added correct RAM sizes as per Charles McDonald's notes
 * Implemented priority in the same manner as tetrisp2
 * Add shadows via custom mixing (gametngk and tetrisp / tp2m32 are much improved)


Date: Sun, 08 Nov 2009 14:59:36 +0000
From: David Haywood <neohaze@nildram.co.uk>
CC: Philip Bennett <p.j.bennett@gmail.com>
Subject: Re: Megasystem 32 ram sizes

and this patch (which replaces the last two) takes things one step 
further, and attempts to add shadows via custom mixing.

in reality per-pixel use of the priority ram will be needed, but this 
does a pretty good job, albeit in a rather unoptimized way.

Shadows in gametngk and tetrisp / tp2m32 are much improved.

David Haywood wrote:
> This implements the priority in the same way as the Standalone Tetris 
> Plus 2 driver, I've also made them share the sprite drawing function 
> (although by the looks of it the older hardware doesn't support sprite 
> zoom)
>
> This isn't perfect as a lot of the priority ram still doesn't get 
> used, but it does make an improvement.
>
> It appears that the places they want to render shadows they draw the 
> sprite under the tilemap, I'm starting to wonder if this is how 
> shadowing works on this hardware (and again, if only the ms32 version 
> of the hardware supports it, because there are some subtle differences 
> in the way things are done in tetris plus 2)  I haven't implemented 
> any shadows yet however.
>
> This replaces the previous patch.
>
> David Haywood wrote:
>> this implements the Jaleco Megasystem 32 RAM Sizes / Widths as per 
>> the notes from Charles MacDonald.  There should be no visible changes 
>> but it at least documents the correct mirrors instead of them being 
>> guessed from game behavior.
This commit is contained in:
Phil Bennett 2009-11-09 09:16:36 +00:00
parent e24aa82627
commit 948d0c66cc
6 changed files with 879 additions and 425 deletions

View File

@ -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.
*/

View File

@ -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

View File

@ -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 );

View File

@ -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 );

View File

@ -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<finish); ms32_reverse_sprite_order ? (source-=8) : (source+=8))
{
attr = source[ 0 ];
if ((attr & 0x0004) == 0) continue;
flipx = attr & 1;
flipy = attr & 2;
pri = (attr >> 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;yy<height;yy++)
{
srcptr_tile = BITMAP_ADDR16(temp_bitmap_tilemaps, yy, 0);
srcptr_tilepri = BITMAP_ADDR8(screen->machine->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<width;xx++)
{
UINT16 src_tile = srcptr_tile[xx];
UINT8 src_tilepri = srcptr_tilepri[xx];
UINT16 src_spri = srcptr_spri[xx];
//UINT8 src_spripri;// = srcptr_spripri[xx];
UINT16 spridat = ((src_spri&0x0fff));
UINT8 spritepri = ((src_spri&0xf000) >> 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);
}
}
}
}

View File

@ -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<finish); reverseorder ? (source-=8) : (source+=8))
{
attr = source[ 0 ];
pri = (attr & 0x00f0);
if ((attr & 0x0004) == 0) continue;
flipx = attr & 1;
@ -406,9 +421,7 @@ static void draw_sprites(running_machine *machine, bitmap_t *bitmap, const recta
tx = (code >> 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;