summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/video/s2636.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/emu/video/s2636.c')
-rw-r--r--src/emu/video/s2636.c300
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;
+}