\r
static __inline void AutoIncrement(void)\r
{\r
- Pico.video.addr=(unsigned short)(Pico.video.addr+Pico.video.reg[0xf]);\r
- if (Pico.video.addr < Pico.video.reg[0xf]) Pico.video.addr_u ^= 1;\r
+ struct PicoVideo *pvid = &Pico.video;\r
+ pvid->addr=(unsigned short)(pvid->addr+pvid->reg[0xf]);\r
+ if (pvid->addr < pvid->reg[0xf]) pvid->addr_u ^= 1;\r
}\r
\r
static NOINLINE void VideoWriteVRAM128(u32 a, u16 d)\r
\r
static void VideoWrite(u16 d)\r
{\r
- unsigned int a = Pico.video.addr;\r
+ struct PicoVideo *pvid = &Pico.video;\r
+ unsigned int a = pvid->addr;\r
\r
- switch (Pico.video.type)\r
+ switch (pvid->type)\r
{\r
case 1: if (a & 1)\r
d = (u16)((d << 8) | (d >> 8));\r
- a |= Pico.video.addr_u << 16;\r
+ a |= pvid->addr_u << 16;\r
VideoWriteVRAM(a, d);\r
break;\r
- case 3: if (PicoMem.cram [(a >> 1) & 0x3f] != d) Pico.m.dirtyPal = 1;\r
+ case 3: if (PicoMem.cram [(a >> 1) & 0x3f] != (d & 0xeee)) Pico.m.dirtyPal = 1;\r
PicoMem.cram [(a >> 1) & 0x3f] = d & 0xeee; break;\r
case 5: PicoMem.vsram[(a >> 1) & 0x3f] = d & 0x7ff; break;\r
case 0x81:\r
- a |= Pico.video.addr_u << 16;\r
+ a |= pvid->addr_u << 16;\r
VideoWriteVRAM128(a, d);\r
break;\r
- //default:elprintf(EL_ANOMALY, "VDP write %04x with bad type %i", d, Pico.video.type); break;\r
+ //default:elprintf(EL_ANOMALY, "VDP write %04x with bad type %i", d, pvid->type); break;\r
}\r
\r
AutoIncrement();\r
\r
static unsigned int VideoRead(int is_from_z80)\r
{\r
+ struct PicoVideo *pvid = &Pico.video;\r
unsigned int a, d = VdpFIFO.fifo_data[(VdpFIFO.fifo_dx+1)&3];\r
\r
- a=Pico.video.addr; a>>=1;\r
+ a=pvid->addr; a>>=1;\r
\r
if (!is_from_z80)\r
SekCyclesBurnRun(PicoVideoFIFORead());\r
- switch (Pico.video.type)\r
+ switch (pvid->type)\r
{\r
case 0: d=PicoMem.vram [a & 0x7fff]; break;\r
case 8: d=PicoMem.cram [a & 0x003f] | (d & ~0x0eee); break;\r
case 4: if ((a & 0x3f) >= 0x28) a = 0;\r
d=PicoMem.vsram [a & 0x003f] | (d & ~0x07ff); break;\r
- case 12:a=PicoMem.vram [a & 0x7fff]; if (Pico.video.addr&1) a >>= 8;\r
+ case 12:a=PicoMem.vram [a & 0x7fff]; if (pvid->addr&1) a >>= 8;\r
d=(a & 0x00ff) | (d & ~0x00ff); break;\r
- default:elprintf(EL_ANOMALY, "VDP read with bad type %i", Pico.video.type); break;\r
+ default:elprintf(EL_ANOMALY, "VDP read with bad type %i", pvid->type); break;\r
}\r
\r
AutoIncrement();\r
\r
static void DmaSlow(int len, u32 source)\r
{\r
- u32 inc = Pico.video.reg[0xf];\r
- u32 a = Pico.video.addr | (Pico.video.addr_u << 16), e;\r
+ struct PicoVideo *pvid=&Pico.video;\r
+ u32 inc = pvid->reg[0xf];\r
+ u32 a = pvid->addr | (pvid->addr_u << 16), e;\r
u16 *r, *base = NULL;\r
u32 mask = 0x1ffff;\r
int lc = SekCyclesDone()-Pico.t.m68c_line_start;\r
\r
elprintf(EL_VDPDMA, "DmaSlow[%i] %06x->%04x len %i inc=%i blank %i [%u] @ %06x",\r
- Pico.video.type, source, a, len, inc, (Pico.video.status&SR_VB)||!(Pico.video.reg[1]&0x40),\r
+ pvid->type, source, a, len, inc, (pvid->status&SR_VB)||!(pvid->reg[1]&0x40),\r
SekCyclesDone(), SekPc);\r
\r
- SekCyclesBurnRun(PicoVideoFIFOWrite(len, FQ_FGDMA | (Pico.video.type == 1),\r
+ SekCyclesBurnRun(PicoVideoFIFOWrite(len, FQ_FGDMA | (pvid->type == 1),\r
PVS_DMABG, SR_DMA | PVS_CPUWR));\r
\r
if ((source & 0xe00000) == 0xe00000) { // Ram\r
base = m68k_dma_source(source);\r
}\r
if (!base) {\r
- elprintf(EL_VDPDMA|EL_ANOMALY, "DmaSlow[%i] %06x->%04x: invalid src", Pico.video.type, source, a);\r
+ elprintf(EL_VDPDMA|EL_ANOMALY, "DmaSlow[%i] %06x->%04x: invalid src", pvid->type, source, a);\r
return;\r
}\r
\r
source >>= 1;\r
mask >>= 1;\r
\r
- switch (Pico.video.type)\r
+ switch (pvid->type)\r
{\r
case 1: // vram\r
e = a + len*2-1;\r
case 3: // cram\r
Pico.m.dirtyPal = 1;\r
r = PicoMem.cram;\r
- if (inc == 0 && (Pico.video.reg[7] & 0x3f) == ((a/2) & 0x3f)) { // bg color DMA\r
+ if (inc == 0 && !(pvid->reg[1] & 0x40) &&\r
+ (pvid->reg[7] & 0x3f) == ((a/2) & 0x3f)) { // bg color DMA\r
PicoVideoSync(1);\r
int sl = VdpFIFO.fifo_hcounts[lc/clkdiv];\r
if (sl > VdpFIFO.fifo_hcounts[0]-5) // hint delay is 5 slots\r
// TODO this is needed to cover timing inaccuracies\r
if (sl <= 12) sl = -2;\r
PicoDrawBgcDMA(base, source, mask, len, sl);\r
+ // do last DMA cycle since it's all going to the same cram location\r
+ source = source+len-1;\r
+ len = 1;\r
}\r
for (; len; len--)\r
{\r
break;\r
\r
default:\r
- if (Pico.video.type != 0 || (EL_LOGMASK & EL_VDPDMA))\r
- elprintf(EL_VDPDMA|EL_ANOMALY, "DMA with bad type %i", Pico.video.type);\r
+ if (pvid->type != 0 || (EL_LOGMASK & EL_VDPDMA))\r
+ elprintf(EL_VDPDMA|EL_ANOMALY, "DMA with bad type %i", pvid->type);\r
break;\r
}\r
// remember addr\r
- Pico.video.addr = a;\r
- Pico.video.addr_u = a >> 16;\r
+ pvid->addr = a;\r
+ pvid->addr_u = a >> 16;\r
}\r
\r
static void DmaCopy(int len)\r
{\r
- u32 a = Pico.video.addr | (Pico.video.addr_u << 16);\r
+ struct PicoVideo *pvid=&Pico.video;\r
+ u32 a = pvid->addr | (pvid->addr_u << 16);\r
u8 *vr = (u8 *)PicoMem.vram;\r
- u8 inc = Pico.video.reg[0xf];\r
+ u8 inc = pvid->reg[0xf];\r
int source;\r
elprintf(EL_VDPDMA, "DmaCopy len %i [%u]", len, SekCyclesDone());\r
\r
SekCyclesBurnRun(PicoVideoFIFOWrite(2*len, FQ_BGDMA, // 2 slots each (rd+wr)\r
PVS_CPUWR, SR_DMA | PVS_DMABG));\r
\r
- source =Pico.video.reg[0x15];\r
- source|=Pico.video.reg[0x16]<<8;\r
+ source =pvid->reg[0x15];\r
+ source|=pvid->reg[0x16]<<8;\r
\r
for (; len; len--)\r
{\r
a = (a+inc) & ~0x20000;\r
}\r
// remember addr\r
- Pico.video.addr = a;\r
- Pico.video.addr_u = a >> 16;\r
+ pvid->addr = a;\r
+ pvid->addr_u = a >> 16;\r
}\r
\r
static NOINLINE void DmaFill(int data)\r
{\r
- u32 a = Pico.video.addr | (Pico.video.addr_u << 16), e;\r
+ struct PicoVideo *pvid=&Pico.video;\r
+ u32 a = pvid->addr | (pvid->addr_u << 16), e;\r
u8 *vr = (u8 *)PicoMem.vram;\r
u8 high = (u8)(data >> 8);\r
- u8 inc = Pico.video.reg[0xf];\r
+ u8 inc = pvid->reg[0xf];\r
int source;\r
int len, l;\r
\r
SekCyclesBurnRun(PicoVideoFIFOWrite(len, FQ_BGDMA, // 1 slot each (wr)\r
PVS_CPUWR | PVS_DMAFILL, SR_DMA | PVS_DMABG));\r
\r
- switch (Pico.video.type)\r
+ switch (pvid->type)\r
{\r
case 1: // vram\r
e = a + len-1;\r
}\r
\r
// remember addr\r
- Pico.video.addr = a;\r
- Pico.video.addr_u = a >> 16;\r
+ pvid->addr = a;\r
+ pvid->addr_u = a >> 16;\r
// register update\r
- Pico.video.reg[0x13] = Pico.video.reg[0x14] = 0;\r
- source = Pico.video.reg[0x15];\r
- source |= Pico.video.reg[0x16] << 8;\r
+ pvid->reg[0x13] = pvid->reg[0x14] = 0;\r
+ source = pvid->reg[0x15];\r
+ source |= pvid->reg[0x16] << 8;\r
source += len;\r
- Pico.video.reg[0x15] = source;\r
- Pico.video.reg[0x16] = source >> 8;\r
-\r
+ pvid->reg[0x15] = source;\r
+ pvid->reg[0x16] = source >> 8;\r
}\r
\r
// VDP command handling\r
}\r
\r
len = GetDmaLength();\r
- source =Pico.video.reg[0x15];\r
- source|=Pico.video.reg[0x16] << 8;\r
- source|=Pico.video.reg[0x17] << 16;\r
+ source = pvid->reg[0x15];\r
+ source |= pvid->reg[0x16] << 8;\r
+ source |= pvid->reg[0x17] << 16;\r
\r
method=pvid->reg[0x17]>>6;\r
if (method < 2)\r
return;\r
}\r
source += len;\r
- Pico.video.reg[0x13] = Pico.video.reg[0x14] = 0;\r
- Pico.video.reg[0x15] = source;\r
- Pico.video.reg[0x16] = source >> 8;\r
+ pvid->reg[0x13] = pvid->reg[0x14] = 0;\r
+ pvid->reg[0x15] = source;\r
+ pvid->reg[0x16] = source >> 8;\r
}\r
\r
static NOINLINE void CommandChange(struct PicoVideo *pvid)\r
SekCyclesBurnRun(PicoVideoFIFOWrite(1, pvid->type == 1, 0, PVS_CPUWR));\r
\r
elprintf(EL_ASVDP, "VDP data write: [%04x] %04x [%u] {%i} @ %06x",\r
- Pico.video.addr, d, SekCyclesDone(), Pico.video.type, SekPc);\r
+ pvid->addr, d, SekCyclesDone(), pvid->type, SekPc);\r
}\r
VideoWrite(d);\r
\r
lineenabled = (d&0x40) ? Pico.m.scanline : -1;\r
linedisabled = (d&0x40) ? -1 : Pico.m.scanline;\r
lineoffset = SekCyclesDone() - Pico.t.m68c_line_start;\r
- } else if (((1<<num) & 0x738ff) && pvid->reg[num] != d)\r
+ } else if (((1<<num) & 0x738ff) && pvid->reg[num] != d)\r
// VDP regs 0-7,11-13,16-18 influence rendering, ignore all others\r
PicoVideoSync(InHblank(93)); // Toy Story\r
pvid->reg[num] = d;\r
\r
PICO_INTERNAL_ASM u32 PicoVideoRead(u32 a)\r
{\r
+ struct PicoVideo *pv = &Pico.video;\r
a &= 0x1c;\r
\r
if (a == 0x04) // control port\r
{\r
- struct PicoVideo *pv = &Pico.video;\r
u32 d = VideoSr(pv);\r
if (pv->pending) {\r
CommandChange(pv);\r
u32 d;\r
\r
c = SekCyclesDone() - Pico.t.m68c_line_start;\r
- if (Pico.video.reg[0]&2)\r
- d = Pico.video.hv_latch;\r
- else d = VdpFIFO.fifo_hcounts[c/clkdiv] | (Pico.video.v_counter << 8);\r
+ if (pv->reg[0]&2)\r
+ d = pv->hv_latch;\r
+ else d = VdpFIFO.fifo_hcounts[c/clkdiv] | (pv->v_counter << 8);\r
\r
- elprintf(EL_HVCNT, "hv: %02x %02x [%u] @ %06x", d, Pico.video.v_counter, SekCyclesDone(), SekPc);\r
+ elprintf(EL_HVCNT, "hv: %02x %02x [%u] @ %06x", d, pv->v_counter, SekCyclesDone(), SekPc);\r
return d;\r
}\r
\r