diff -Nru src/emu/video/tms9928a.c 2/src/emu/video/tms9928a.c --- src/emu/video/tms9928a.c 2008-12-08 16:13:47.000000000 +0100 +++ src/emu/video/tms9928a.c 2008-12-09 17:28:29.000000000 +0100 @@ -35,14 +35,20 @@ ** - Got rid of the color table, unused. Also got rid of the old colors, ** which were commented out anyway. ** +** 9 dec 2008, hap: +** - Removed concept of "FirstByte" when writing. The address is always +** updated immediately. ( WRITE8_HANDLER (TMS9928A_register_w) ) +** - Fixed undocumented behaviour of sprite overflow bit. +** ** ** Todo: ** - The screen image is rendered in `one go'. Modifications during -** screen build up are not shown. +** screen build up are not shown/emulated. ** - Correctly emulate 4,8,16 kb VRAM if needed. ** - uses plot _pixel (...) in TMS_sprites (...), which is rended in ** in a back buffer created with malloc (). Hmm.. -** - Colours are incorrect. [fixed by R Nabet ?] +** - Sprite planes 8-31 cloning when using undocumented M3 mirrored mode. +** Temperature related, the effect dissipates if you blow dry the chip! :) */ #include "driver.h" @@ -134,7 +140,7 @@ typedef struct { /* TMS9928A internal settings */ - UINT8 ReadAhead,Regs[8],StatusReg,FirstByte,latch,INT; + UINT8 ReadAhead,Regs[8],StatusReg,latch,INT; INT32 Addr; int colour,pattern,nametbl,spriteattribute,spritepattern; int colourmask,patternmask; @@ -172,8 +178,7 @@ tms.spritepattern = tms.spriteattribute = 0; tms.colourmask = tms.patternmask = 0; tms.Addr = tms.ReadAhead = tms.INT = 0; - tms.FirstByte = 0; - tms.latch = 0; + tms.latch = 0; } static void TMS9928A_start (running_machine *machine, const TMS9928a_interface *intf) @@ -222,7 +227,6 @@ state_save_register_item(machine, "tms9928a", NULL, 0, tms.Regs[7]); state_save_register_item(machine, "tms9928a", NULL, 0, tms.StatusReg); state_save_register_item(machine, "tms9928a", NULL, 0, tms.ReadAhead); - state_save_register_item(machine, "tms9928a", NULL, 0, tms.FirstByte); state_save_register_item(machine, "tms9928a", NULL, 0, tms.latch); state_save_register_item(machine, "tms9928a", NULL, 0, tms.Addr); state_save_register_item(machine, "tms9928a", NULL, 0, tms.INT); @@ -280,27 +284,28 @@ } WRITE8_HANDLER (TMS9928A_register_w) { - int reg; - - if (tms.latch) { - if (data & 0x80) { - /* register write */ - reg = data & 7; - /*if (tms.FirstByte != tms.Regs[reg])*/ /* Removed to fix ColecoVision MESS Driver*/ - change_register (space->machine, reg, tms.FirstByte); - } else { - /* set read/write address */ - tms.Addr = ((UINT16)data << 8 | tms.FirstByte) & (tms.vramsize - 1); - if ( !(data & 0x40) ) { - /* read ahead */ - TMS9928A_vram_r (space,0); - } - } - tms.latch = 0; - } else { - tms.FirstByte = data; + if (tms.latch) { + tms.Addr = ((UINT16)data << 8 | (tms.Addr&0xff)) & (tms.vramsize - 1); + + if (data & 0x80) { + /* register write */ + + /*if ((tms.Addr&0xff) != tms.Regs[data&7])*/ /* Removed to fix ColecoVision MESS Driver*/ + change_register (space->machine, data&7, tms.Addr&0xff); + } + + else if ( !(data & 0x40) ) { + /* read ahead */ + TMS9928A_vram_r (space,0); + } + + tms.latch = 0; + } + else { + tms.Addr = ((data&0xff) | (tms.Addr&0xff00)) & (tms.vramsize - 1); + tms.latch = 1; - } + } } static void change_register (running_machine *machine, int reg, UINT8 val) { @@ -663,7 +668,7 @@ large = (int)(tms.Regs[1] & 1); for (x=0;x<192;x++) limit[x] = 4; - tms.StatusReg = 0x80; + tms.StatusReg&=0xdf; /* reset collision */ illegalspriteline = 255; illegalsprite = 0; @@ -777,10 +782,17 @@ } } } - if (illegalspriteline == 255) { - tms.StatusReg |= (p > 31) ? 31 : p; - } else { - tms.StatusReg |= 0x40 + illegalsprite; + + /* The sprite number is only updated if the overflow bit is clear, + and the overflow bit will only be set if bit 6 and 7 are both clear. */ + if (!(tms.StatusReg&0x40)) { + if (illegalspriteline == 255) { + tms.StatusReg |= (p > 31) ? 31 : p; + } + else { + tms.StatusReg |= illegalsprite; + if (!(tms.StatusReg&0x80)) tms.StatusReg |= 0x40; + } } }