diff options
Diffstat (limited to 'src/emu/video/s2636.c')
-rw-r--r-- | src/emu/video/s2636.c | 300 |
1 files changed, 300 insertions, 0 deletions
diff --git a/src/emu/video/s2636.c b/src/emu/video/s2636.c new file mode 100644 index 00000000000..664399e4834 --- /dev/null +++ b/src/emu/video/s2636.c @@ -0,0 +1,300 @@ +/************************************************************* + * * + * Signetics 2636 video chip * + * * + ************************************************************* + + PVI REGISTER DESCRIPTION + ------------------------ + + | bit |R/W| description + byte | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | | + | | | + FC0 | size 4| size 3| size 2| size 1| W | size of the 4 objects(=sprites) + | | | + FC1 | |C1 |C2 |C3 |C1 |C2 |C3 | W | colours of the 4 objects + | | colour 1 | colour 2 | | + FC2 | |C1 |C2 |C3 |C1 |C2 |C3 | W | + | | colour 3 | colour 4 | | + | | | + FC3 | |sh |pos| W | 1=shape 0=position + | | | display format and position + FC4 | (free) | | + FC5 | (free) | | + | | | + FC6 | |C1 |C2 |C3 |BG |scrn colr | W | background lock and colour + | |backg colr |enb|C1 |C2 |C3 | | 3="enable" + | | | + FC7 | sound | W | squarewave output + | | | + FC8 | N1 | N2 | W | range of the 4 display digits + FC9 | N3 | N4 | W | + | | | + |obj/backgrnd |complete object| R | + FCA | 1 | 2 | 3 | 4 | 1 | 2 | 3 | 4 | | + | | | + FCB | |VR-| object collisions | R | Composition of object and back- + | |LE |1/2|1/3|1/3|1/4|2/4|3/4| | ground,collision detection and + | | | object display as a state display + | | | for the status register.Set VRLE. + | | | wait for VRST.Read out or transmit + | | | [copy?] all bits until reset by + | | | VRST. + | | | + FCC | PORT1 | R | PORT1 and PORT2 for the range of + FCD | PORT2 | | the A/D conversion.Cleared by VRST + FCE | (free) | | + FCF | (free) | | + + + Size control by byte FC0 + + bit matrix + |0|0| 8x10 + |0|1| 16x20 + |1|0| 32x40 + |1|1| 64x80 + + CE1 and not-CE2 are outputs from the PVI.$E80..$EFF also controls the + analogue multiplexer. + + + SPRITES + ------- + + each object field: (=sprite data structure) + + 0 \ 10 bytes of bitmap (Each object is 8 pixels wide.) + 9 / + A HC horizontal object coordinate + B HCB horizontal dublicate coordinate + C VC vertical object coordinate + D VCB vertical dublicate coordinate + + *************************************************************/ + +#include "driver.h" +#include "s2636.h" + +static int SpriteOffset[4] = {0,0x10,0x20,0x40}; + +/* To adjust sprites against bitmap */ + +UINT8 *s2636_1_ram; +UINT8 *s2636_2_ram; +UINT8 *s2636_3_ram; + +mame_bitmap *s2636_1_bitmap; +mame_bitmap *s2636_2_bitmap; +mame_bitmap *s2636_3_bitmap; + +UINT8 s2636_1_dirty[4]; +UINT8 s2636_2_dirty[4]; +UINT8 s2636_3_dirty[4]; + +int s2636_x_offset=0; +int s2636_y_offset=0; + +void s2636_w(UINT8 *workram,int offset,int data,UINT8 *dirty) +{ + if (workram[offset] != data) + { + workram[offset] = data; + + if(offset < 10) + dirty[0]=1; + else + { + if((offset > 15) && (offset < 26)) + dirty[1]=1; + else + { + if((offset > 31) && (offset < 42)) + dirty[2]=1; + else + { + if((offset > 63) && (offset < 74)) + dirty[3]=1; + } + } + } + } +} + +/*****************************************/ +/* Check for Collision between 2 sprites */ +/*****************************************/ + +static int SpriteCheck(running_machine *machine, int first,int second,UINT8 *workram,int Graphics_Bank,mame_bitmap *collision_bitmap) +{ + int Checksum=0; + int x,y; + + // Does not check shadow sprites yet + + if((workram[SpriteOffset[first] + 10] != 0xff) && (workram[SpriteOffset[second] + 10] != 0xff)) + { + int fx1 = workram[SpriteOffset[first] + 10] + s2636_x_offset; + int fy1 = workram[SpriteOffset[first] + 12] + s2636_y_offset; + int fx2 = workram[SpriteOffset[second] + 10] + s2636_x_offset; + int fy2 = workram[SpriteOffset[second] + 12] + s2636_y_offset; + + if((fx1>=0) && (fy1>=0) && (fx2>=0) && (fy2>=0)) + { + int expand1 = 1 << (16+((workram[0xC0]>>(first<<1)) & 3)); + int expand2 = 1 << (16+((workram[0xC0]>>(second<<1)) & 3)); + + int char1 = SpriteOffset[first]>>4; + int char2 = SpriteOffset[second]>>4; + + /* Draw first sprite */ + + drawgfxzoom(collision_bitmap,machine->gfx[Graphics_Bank], + char1, + 1, + 0,0, + fx1,fy1, + &machine->screen[0].visarea, TRANSPARENCY_PEN, 0, + expand1,expand1); + + /* Get fingerprint */ + + for (x = fx1; x < fx1 + machine->gfx[Graphics_Bank]->width; x++) + { + for (y = fy1; y < fy1 + machine->gfx[Graphics_Bank]->height; y++) + { + if ((x < machine->screen[0].visarea.min_x) || + (x > machine->screen[0].visarea.max_x) || + (y < machine->screen[0].visarea.min_y) || + (y > machine->screen[0].visarea.max_y)) + { + continue; + } + + Checksum += *BITMAP_ADDR8(collision_bitmap, y, x); + } + } + + /* Blackout second sprite */ + + drawgfxzoom(collision_bitmap,machine->gfx[Graphics_Bank], + char2, + 0, + 0,0, + fx2,fy2, + &machine->screen[0].visarea, TRANSPARENCY_PEN, 0, + expand2,expand2); + + /* Remove fingerprint */ + + for (x = fx1; x < fx1 + machine->gfx[Graphics_Bank]->width; x++) + { + for (y = fy1; y < fy1 + machine->gfx[Graphics_Bank]->height; y++) + { + if ((x < machine->screen[0].visarea.min_x) || + (x > machine->screen[0].visarea.max_x) || + (y < machine->screen[0].visarea.min_y) || + (y > machine->screen[0].visarea.max_y)) + { + continue; + } + + Checksum -= *BITMAP_ADDR8(collision_bitmap, y, x); + } + } + + /* Zero bitmap */ + + drawgfxzoom(collision_bitmap,machine->gfx[Graphics_Bank], + char1, + 0, + 0,0, + fx1,fy1, + &machine->screen[0].visarea, TRANSPARENCY_PEN, 0, + expand1,expand1); + } + } + + return Checksum; +} + +void s2636_update_bitmap(running_machine *machine,mame_bitmap *bitmap,UINT8 *workram,UINT8 *dirty,int Graphics_Bank,mame_bitmap *collision_bitmap) +{ + int CollisionSprite = 0; + int spriteno; + int offs; + + for(spriteno=0;spriteno<4;spriteno++) + { + offs = SpriteOffset[spriteno]; + + if(workram[offs+10]!=0xFF) + { + int charno = offs>>4; + int expand = 1 << (16+((workram[0xC0]>>(spriteno<<1)) & 3)); + int bx = workram[offs+10] + s2636_x_offset; + int by = workram[offs+12] + s2636_y_offset; + + if((bx >= 0) && (by >= 0)) + { + /* Get colour and mask correct bits */ + + int colour = workram[0xC1 + (spriteno >> 1)]; + + if((spriteno & 1)==0) colour >>= 3; + + colour = (colour & 7) + 7; + + if(dirty[spriteno]) + { + decodechar(machine->gfx[Graphics_Bank],charno,workram,machine->drv->gfxdecodeinfo[Graphics_Bank].gfxlayout); + dirty[spriteno] = 0; + } + + drawgfxzoom(bitmap,machine->gfx[Graphics_Bank], + charno, + colour, + 0,0, + bx,by, + &machine->screen[0].visarea, + TRANSPARENCY_BLEND_RAW, 0, + expand,expand); + + /* Shadow Sprites */ + + if((workram[offs+11]!=0xff) && (workram[offs+13]!=0xfe)) + { + bx=workram[offs+11] + s2636_x_offset; + + if(bx >= 0) + { + for(;by < 255;) + { + by=by+10+workram[offs+13]; + + drawgfxzoom(bitmap,machine->gfx[Graphics_Bank], + charno, + colour, + 0,0, + bx,by, + &machine->screen[0].visarea, + TRANSPARENCY_BLEND_RAW, 0, + expand,expand); + } + } + } + } + } + } + + /* Sprite->Sprite collision detection */ + + if(SpriteCheck(machine,0,1,workram,Graphics_Bank,collision_bitmap)) CollisionSprite |= 0x20; + if(SpriteCheck(machine,0,2,workram,Graphics_Bank,collision_bitmap)) CollisionSprite |= 0x10; + if(SpriteCheck(machine,0,3,workram,Graphics_Bank,collision_bitmap)) CollisionSprite |= 0x08; + if(SpriteCheck(machine,1,2,workram,Graphics_Bank,collision_bitmap)) CollisionSprite |= 0x04; + if(SpriteCheck(machine,1,3,workram,Graphics_Bank,collision_bitmap)) CollisionSprite |= 0x02; + if(SpriteCheck(machine,2,3,workram,Graphics_Bank,collision_bitmap)) CollisionSprite |= 0x01; + + workram[0xCB] = CollisionSprite; +} |