X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;ds=inline;f=pico%2Fvideoport.c;h=1f57f2d4f04d0b89743b2be4957182398ee384b3;hb=ebd70cb5d9b32eb6548f92e03639db5c0683100f;hp=3f26d581ecb13b56918b35e377d10edbea9836a4;hpb=0c7d1ba332b26f4ac67199e8ecbb826651f8512a;p=picodrive.git diff --git a/pico/videoport.c b/pico/videoport.c index 3f26d58..1f57f2d 100644 --- a/pico/videoport.c +++ b/pico/videoport.c @@ -29,6 +29,13 @@ static __inline void AutoIncrement(void) Pico.video.addr=(unsigned short)(Pico.video.addr+Pico.video.reg[0xf]); } +static NOINLINE void VideoWrite128(u32 a, u16 d) +{ + // nasty + a = ((a & 2) >> 1) | ((a & 0x400) >> 9) | (a & 0x3FC) | ((a & 0x1F800) >> 1); + ((u8 *)Pico.vram)[a] = d; +} + static void VideoWrite(u16 d) { unsigned int a=Pico.video.addr; @@ -43,6 +50,10 @@ static void VideoWrite(u16 d) case 3: Pico.m.dirtyPal = 1; Pico.cram [(a>>1)&0x003f]=d; break; // wraps (Desert Strike) case 5: Pico.vsram[(a>>1)&0x003f]=d; break; + case 0x81: + a |= Pico.video.addr_u << 16; + VideoWrite128(a, d); + break; //default:elprintf(EL_ANOMALY, "VDP write %04x with bad type %i", d, Pico.video.type); break; } @@ -186,6 +197,17 @@ static void DmaSlow(int len, unsigned int source) } break; + case 0x81: // vram 128k + a |= Pico.video.addr_u << 16; + for(; len; len--) + { + VideoWrite128(a, base[source++ & mask]); + // AutoIncrement + a = (a + inc) & 0x1ffff; + } + Pico.video.addr_u = a >> 16; + break; + default: if (Pico.video.type != 0 || (EL_LOGMASK & EL_VDPDMA)) elprintf(EL_VDPDMA|EL_ANOMALY, "DMA with bad type %i", Pico.video.type); @@ -201,7 +223,7 @@ static void DmaCopy(int len) unsigned char *vr = (unsigned char *) Pico.vram; unsigned char inc=Pico.video.reg[0xf]; int source; - elprintf(EL_VDPDMA, "DmaCopy len %i [%i]", len, SekCyclesDone()); + elprintf(EL_VDPDMA, "DmaCopy len %i [%u]", len, SekCyclesDone()); Pico.m.dma_xfers += len; if (Pico.m.dma_xfers < len) @@ -232,7 +254,7 @@ static NOINLINE void DmaFill(int data) int len, l; len = GetDmaLength(); - elprintf(EL_VDPDMA, "DmaFill len %i inc %i [%i]", len, inc, SekCyclesDone()); + elprintf(EL_VDPDMA, "DmaFill len %i inc %i [%u]", len, inc, SekCyclesDone()); Pico.m.dma_xfers += len; if (Pico.m.dma_xfers < len) // lame 16bit var @@ -303,20 +325,23 @@ static NOINLINE void CommandDma(void) Pico.video.reg[0x16] = source >> 8; } -static void CommandChange(void) +static NOINLINE void CommandChange(void) { - struct PicoVideo *pvid=&Pico.video; - unsigned int cmd=0,addr=0; + struct PicoVideo *pvid = &Pico.video; + unsigned int cmd, addr; - cmd=pvid->command; + cmd = pvid->command; // Get type of transfer 0xc0000030 (v/c/vsram read/write) - pvid->type=(unsigned char)(((cmd>>2)&0xc)|(cmd>>30)); + pvid->type = (u8)(((cmd >> 2) & 0xc) | (cmd >> 30)); + if (pvid->type == 1) // vram + pvid->type |= pvid->reg[1] & 0x80; // 128k // Get address 0x3fff0003 - addr =(cmd>>16)&0x3fff; - addr|=(cmd<<14)&0xc000; - pvid->addr=(unsigned short)addr; + addr = (cmd >> 16) & 0x3fff; + addr |= (cmd << 14) & 0xc000; + pvid->addr = (u16)addr; + pvid->addr_u = (u8)((cmd >> 2) & 1); } static void DrawSync(int blank_on) @@ -336,8 +361,9 @@ PICO_INTERNAL_ASM void PicoVideoWrite(unsigned int a,unsigned short d) // elprintf(EL_STATUS, "PicoVideoWrite [%06x] %04x", a, d); a&=0x1c; - if (a==0x00) // Data port 0 or 2 + switch (a) { + case 0x00: // Data port 0 or 2 // try avoiding the sync.. if (Pico.m.scanline < 224 && (pvid->reg[1]&0x40) && !(!pvid->pending && @@ -367,11 +393,9 @@ PICO_INTERNAL_ASM void PicoVideoWrite(unsigned int a,unsigned short d) if ((pvid->command&0x80) && (pvid->reg[1]&0x10) && (pvid->reg[0x17]>>6)==2) DmaFill(d); - return; - } + break; - if (a==0x04) // Control (command) port 4 or 6 - { + case 0x04: // Control (command) port 4 or 6 if (pvid->pending) { // Low word of command: @@ -406,11 +430,11 @@ PICO_INTERNAL_ASM void PicoVideoWrite(unsigned int a,unsigned short d) switch (num) { case 0x00: - elprintf(EL_INTSW, "hint_onoff: %i->%i [%i] pend=%i @ %06x", (dold&0x10)>>4, + elprintf(EL_INTSW, "hint_onoff: %i->%i [%u] pend=%i @ %06x", (dold&0x10)>>4, (d&0x10)>>4, SekCyclesDone(), (pvid->pending_ints&0x10)>>4, SekPc); goto update_irq; case 0x01: - elprintf(EL_INTSW, "vint_onoff: %i->%i [%i] pend=%i @ %06x", (dold&0x20)>>5, + elprintf(EL_INTSW, "vint_onoff: %i->%i [%u] pend=%i @ %06x", (dold&0x20)>>5, (d&0x20)>>5, SekCyclesDone(), (pvid->pending_ints&0x20)>>5, SekPc); goto update_irq; case 0x05: @@ -448,6 +472,35 @@ update_irq: pvid->pending=1; } } + break; + + // case 0x08: // 08 0a - HV counter - lock up + // case 0x0c: // 0c 0e - HV counter - lock up + // case 0x10: // 10 12 - PSG - handled by caller + // case 0x14: // 14 16 - PSG - handled by caller + // case 0x18: // 18 1a - no effect? + case 0x1c: // 1c 1e - debug + pvid->debug = d; + pvid->debug_p = 0; + if (d & (1 << 6)) { + pvid->debug_p |= PVD_KILL_A | PVD_KILL_B; + pvid->debug_p |= PVD_KILL_S_LO | PVD_KILL_S_HI; + } + switch ((d >> 7) & 3) { + case 1: + pvid->debug_p &= ~(PVD_KILL_S_LO | PVD_KILL_S_HI); + pvid->debug_p |= PVD_FORCE_S; + break; + case 2: + pvid->debug_p &= ~PVD_KILL_A; + pvid->debug_p |= PVD_FORCE_A; + break; + case 3: + pvid->debug_p &= ~PVD_KILL_B; + pvid->debug_p |= PVD_FORCE_B; + break; + } + break; } } @@ -498,7 +551,7 @@ PICO_INTERNAL_ASM unsigned int PicoVideoRead(unsigned int a) d = hcounts_40[d]; else d = hcounts_32[d]; - elprintf(EL_HVCNT, "hv: %02x %02x (%i) @ %06x", d, Pico.video.v_counter, SekCyclesDone(), SekPc); + elprintf(EL_HVCNT, "hv: %02x %02x [%u] @ %06x", d, Pico.video.v_counter, SekCyclesDone(), SekPc); return d | (Pico.video.v_counter << 8); } @@ -510,43 +563,54 @@ PICO_INTERNAL_ASM unsigned int PicoVideoRead(unsigned int a) return 0; } -unsigned int PicoVideoRead8(unsigned int a) +unsigned char PicoVideoRead8DataH(void) { - unsigned int d; - a&=0x1d; + return VideoRead() >> 8; +} - switch (a) - { - case 0: return VideoRead() >> 8; - case 1: return VideoRead() & 0xff; - case 4: // control port/status reg - d = Pico.video.status >> 8; - if (d&1) Pico.video.status&=~0x100; // FIFO no longer full - Pico.video.pending = 0; - elprintf(EL_SR, "SR read (h): %02x @ %06x", d, SekPc); - return d; - case 5: - d = Pico.video.status & 0xff; - //if (PicoOpt&POPT_ALT_RENDERER) d|=0x0020; // sprite collision (Shadow of the Beast) - d |= ((Pico.video.reg[1]&0x40)^0x40) >> 3; // set V-Blank if display is disabled - d |= (Pico.video.pending_ints&0x20)<<2; // V-int pending? - if (SekCyclesDone() - line_base_cycles >= 488-88) d |= 4; // H-Blank - Pico.video.pending = 0; - elprintf(EL_SR, "SR read (l): %02x @ %06x", d, SekPc); - return d; - case 8: // hv counter - elprintf(EL_HVCNT, "vcounter: %02x (%i) @ %06x", Pico.video.v_counter, SekCyclesDone(), SekPc); - return Pico.video.v_counter; - case 9: - d = (SekCyclesDone() - line_base_cycles) & 0x1ff; // FIXME - if (Pico.video.reg[12]&1) - d = hcounts_40[d]; - else d = hcounts_32[d]; - elprintf(EL_HVCNT, "hcounter: %02x (%i) @ %06x", d, SekCyclesDone(), SekPc); - return d; - } +unsigned char PicoVideoRead8DataL(void) +{ + return VideoRead(); +} - return 0; +// FIXME: broken mess +unsigned char PicoVideoRead8CtlH(void) +{ + u8 d = (u8)(Pico.video.status >> 8); + if (d & 1) + Pico.video.status &= ~0x100; // FIFO no longer full + Pico.video.pending = 0; + elprintf(EL_SR, "SR read (h): %02x @ %06x", d, SekPc); + return d; +} + +unsigned char PicoVideoRead8CtlL(void) +{ + u8 d = (u8)Pico.video.status; + //if (PicoOpt&POPT_ALT_RENDERER) d|=0x0020; // sprite collision (Shadow of the Beast) + d |= ((Pico.video.reg[1]&0x40)^0x40) >> 3; // set V-Blank if display is disabled + d |= (Pico.video.pending_ints&0x20)<<2; // V-int pending? + if (SekCyclesDone() - line_base_cycles >= 488-88) d |= 4; // H-Blank + Pico.video.pending = 0; + elprintf(EL_SR, "SR read (l): %02x @ %06x", d, SekPc); + return d; +} + +unsigned char PicoVideoRead8HV_H(void) +{ + elprintf(EL_HVCNT, "vcounter: %02x [%u] @ %06x", Pico.video.v_counter, SekCyclesDone(), SekPc); + return Pico.video.v_counter; +} + +// FIXME: broken +unsigned char PicoVideoRead8HV_L(void) +{ + u32 d = (SekCyclesDone() - line_base_cycles) & 0x1ff; // FIXME + if (Pico.video.reg[12]&1) + d = hcounts_40[d]; + else d = hcounts_32[d]; + elprintf(EL_HVCNT, "hcounter: %02x [%u] @ %06x", d, SekCyclesDone(), SekPc); + return d; } // vim:shiftwidth=2:ts=2:expandtab