u32 fifo_queue[8], fifo_qx, fifo_ql;\r
int fifo_total; // total# of pending FIFO entries (w/o BGDMA)\r
\r
+ int fifo_cnt; // remaining entries in currently active transfer\r
unsigned short fifo_slot; // last executed slot in current scanline\r
unsigned short fifo_maxslot;// #slots in scanline\r
\r
static __inline int AdvanceFIFOEntry(struct VdpFIFO *vf, struct PicoVideo *pv, int slots)\r
{\r
int l = slots, b = vf->fifo_queue[vf->fifo_qx] & FQ_BYTE;\r
- int cnt = pv->fifo_cnt;\r
+ int cnt = vf->fifo_cnt;\r
\r
// advance currently active FIFO entry\r
if (l > cnt)\r
if (!(vf->fifo_queue[vf->fifo_qx] & FQ_BGDMA))\r
vf->fifo_total -= ((cnt & b) + l) >> b;\r
cnt -= l;\r
- pv->fifo_cnt = cnt;\r
+ vf->fifo_cnt = cnt;\r
\r
// if entry has been processed...\r
if (cnt == 0) {\r
// start processing for next entry if there is one\r
if (vf->fifo_ql) {\r
b = vf->fifo_queue[vf->fifo_qx] & FQ_BYTE;\r
- pv->fifo_cnt = (vf->fifo_queue[vf->fifo_qx] >> 3) << b;\r
+ vf->fifo_cnt = (vf->fifo_queue[vf->fifo_qx] >> 3) << b;\r
} else { // FIFO empty\r
pv->status &= ~PVS_FIFORUN;\r
vf->fifo_total = 0;\r
cmd &= ~0x80;\r
}\r
}\r
- if (pv->fifo_cnt == 0) {\r
+ if (vf->fifo_cnt == 0) {\r
st &= ~PVS_CPURD;\r
// terminate DMA if applicable\r
if (!(st & (PVS_FIFORUN|PVS_DMAFILL))) {\r
\r
// advance FIFO queue by #done slots\r
done = slots;\r
- while (done > 0 && pv->fifo_cnt) {\r
+ while (done > 0 && vf->fifo_cnt) {\r
int l = AdvanceFIFOEntry(vf, pv, done);\r
vf->fifo_slot += l;\r
done -= l;\r
while (vf->fifo_slot < vf->fifo_maxslot &&\r
vf->fifo_ql && ((vf->fifo_total > level) | bd)) {\r
int b = vf->fifo_queue[vf->fifo_qx] & FQ_BYTE;\r
- int cnt = bd ? pv->fifo_cnt : ((vf->fifo_total-level)<<b) - (pv->fifo_cnt&b);\r
- int slot = (pv->fifo_cnt<cnt ? pv->fifo_cnt:cnt) + vf->fifo_slot;\r
+ int cnt = bd ? vf->fifo_cnt : ((vf->fifo_total-level)<<b) - (vf->fifo_cnt&b);\r
+ int slot = (vf->fifo_cnt<cnt ? vf->fifo_cnt:cnt) + vf->fifo_slot;\r
\r
if (slot > vf->fifo_maxslot) {\r
// target slot in later scanline, advance to eol\r
int lc = SekCyclesDone()-Pico.t.m68c_line_start;\r
int burn = 0;\r
\r
- if (pv->fifo_cnt) {\r
+ if (vf->fifo_cnt) {\r
PicoVideoFIFOSync(lc);\r
// advance FIFO and CPU until FIFO is empty\r
burn = PicoVideoFIFODrain(0, lc, FQ_BGDMA);\r
lc += burn;\r
}\r
\r
- if (pv->fifo_cnt)\r
+ if (vf->fifo_cnt)\r
pv->status |= PVS_CPURD; // target slot is in later scanline\r
else {\r
// use next VDP access slot for reading, block 68k until then\r
int lc = SekCyclesDone()-Pico.t.m68c_line_start;\r
int burn = 0;\r
\r
- if (pv->fifo_cnt)\r
+ if (vf->fifo_cnt)\r
PicoVideoFIFOSync(lc);\r
pv->status = (pv->status & ~sr_mask) | sr_flags;\r
\r
// XXX if interrupting a DMA fill, fill data changes\r
if (x == vf->fifo_qx) { // overtaking to queue head?\r
int f = vf->fifo_queue[x] & 7;\r
- vf->fifo_queue[x] = (pv->fifo_cnt >> (f & FQ_BYTE) << 3) | f;\r
+ vf->fifo_queue[x] = (vf->fifo_cnt >> (f & FQ_BYTE) << 3) | f;\r
pv->status &= ~PVS_FIFORUN;\r
}\r
// push background DMA back\r
// amalgamate entries if of same type\r
vf->fifo_queue[x] += (count << 3);\r
if (x == vf->fifo_qx)\r
- pv->fifo_cnt += count << (flags & FQ_BYTE);\r
+ vf->fifo_cnt += count << (flags & FQ_BYTE);\r
} else {\r
// create new xfer queue entry\r
vf->fifo_ql ++;\r
if (!(pv->status & PVS_FIFORUN)) {\r
vf->fifo_slot = Cyc2Sl(vf, lc+7); // FIFO latency ~3 vdp slots\r
pv->status |= PVS_FIFORUN;\r
- pv->fifo_cnt = count << (flags & FQ_BYTE);\r
+ vf->fifo_cnt = count << (flags & FQ_BYTE);\r
}\r
if (!(flags & FQ_BGDMA))\r
vf->fifo_total += count;\r
\r
static NOINLINE void CommandDma(void)\r
{\r
- struct PicoVideo *pvid=&Pico.video;\r
+ struct PicoVideo *pvid = &Pico.video;\r
u32 len, method;\r
u32 source;\r
\r
if (pvid->status & SR_DMA) {\r
elprintf(EL_VDPDMA, "Dma overlap, left=%d @ %06x",\r
VdpFIFO.fifo_total, SekPc);\r
- pvid->fifo_cnt = VdpFIFO.fifo_total = VdpFIFO.fifo_ql = 0;\r
+ VdpFIFO.fifo_cnt = VdpFIFO.fifo_total = VdpFIFO.fifo_ql = 0;\r
pvid->status &= ~(PVS_FIFORUN|PVS_DMAFILL);\r
}\r
\r
int l, x;\r
\r
// account for all outstanding xfers XXX kludge, entry attr's not saved\r
+ pv->fifo_cnt = vf->fifo_cnt;\r
for (l = vf->fifo_ql, x = vf->fifo_qx + l-1; l > 1; l--, x--)\r
pv->fifo_cnt += (vf->fifo_queue[x&7] >> 3) << (vf->fifo_queue[x&7] & FQ_BYTE);\r
}\r
Pico.m.dma_xfers = 0;\r
}\r
// make an entry in the FIFO if there are outstanding transfers\r
- vf->fifo_ql = vf->fifo_total = 0;\r
+ vf->fifo_ql = vf->fifo_qx = vf->fifo_total = 0;\r
if (pv->fifo_cnt) {\r
+ int wc = (pv->fifo_cnt + b) >> b;\r
pv->status |= PVS_FIFORUN|PVS_CPUWR;\r
+ vf->fifo_cnt = pv->fifo_cnt;\r
if (!(pv->status & PVS_DMABG))\r
- vf->fifo_total = (pv->fifo_cnt + b) >> b;\r
+ vf->fifo_total = wc;\r
if ((pv->status & SR_DMA) && !(pv->status & PVS_DMAFILL))\r
b |= (pv->status & PVS_DMABG) ? FQ_BGDMA : FQ_FGDMA;\r
- vf->fifo_queue[vf->fifo_qx] = (vf->fifo_total << 3) | b;\r
+ vf->fifo_queue[vf->fifo_qx] = (wc << 3) | b;\r
vf->fifo_ql = 1;\r
}\r
PicoVideoCacheSAT();\r