]> git.lizzy.rs Git - plan9front.git/blobdiff - sys/src/games/nes/mem.c
games/nes: it's too late to write code
[plan9front.git] / sys / src / games / nes / mem.c
index 5b983ea32fa56e7f5f5ac4c95f026b40b9dbfd62..79297a9779809c507cee8c5efa8e9ae795e16e71 100644 (file)
@@ -137,6 +137,70 @@ t:
        }
 }
 
+static void
+uxrom(int p, u8int v)
+{
+       static u8int b;
+       
+       if(p < 0)
+               switch(p){
+               case INIT:
+                       prgsh = 14;
+                       chrsh = 13;
+                       prgb[1] = prg + (nprg - 1) * 0x4000;
+                       chrb[0] = chr;
+                       break;
+               case SAVE:
+                       put8(b);
+                       return;
+               case RSTR:
+                       b = get8();
+                       break;
+               case SCAN:
+                       return;
+               default:
+                       nope(p);
+                       return;
+               }
+       else
+               b = v % nprg;
+       prgb[0] = prg + b * 0x4000;
+}
+
+static void
+cnrom(int p, u8int v)
+{
+       static u8int b;
+       
+       if(p < 0)
+               switch(p){
+               case INIT:
+                       prgsh = 14;
+                       chrsh = 13;
+                       prgb[0] = prg;
+                       if(nprg == 1)
+                               prgb[1] = prg;
+                       else
+                               prgb[1] = prg + 0x4000;
+                       break;
+               case SAVE:
+                       put8(b);
+                       return;
+               case RSTR:
+                       b = get8();
+                       break;
+               case SCAN:
+                       return;
+               default:
+                       nope(p);
+                       return;
+               }
+       else
+               b = v % nchr;
+       chrb[0] = chr + b * 0x2000;
+
+}
+
 static void
 mmc3(int p, u8int v)
 {
@@ -158,7 +222,7 @@ mmc3(int p, u8int v)
                        else
                                n--;
                        if(n == 0 && en)
-                               irq |= 2;
+                               irq |= IRQMMC;
                        return;
                case SAVE:
                        put8(m);
@@ -204,7 +268,7 @@ mmc3(int p, u8int v)
                break;
        case 0xC000: l = v; break;
        case 0xC001: n = 0; break;
-       case 0xE000: en = 0; irq &= ~2; break;
+       case 0xE000: en = 0; irq &= ~IRQMMC; break;
        case 0xE001: en = 1; break;
        }
        return;
@@ -258,6 +322,8 @@ axrom(int p, u8int v)
 void (*mapper[256])(int, u8int) = {
        [0] nrom,
        [1] mmc1,
+       [2] uxrom,
+       [3] cnrom,
        [4] mmc3,
        [7] axrom,
 };
@@ -281,6 +347,7 @@ u8int
 memread(u16int p)
 {
        u8int v;
+       int i;
 
        if(p < 0x2000){
                p &= 0x7FF;
@@ -305,6 +372,16 @@ memread(u16int p)
                        vrambuf = ppuread(ppuv);
                        incvram();
                        return vrambuf;
+               case APUSTATUS:
+                       v = (irq & 3) << 6;
+                       for(i = 0; i < 4; i++){
+                               if(apuctr[i] != 0)
+                                       v |= (1<<i);
+                       }
+                       if(mem[0x4013] != 0)
+                               v |= (1<<4);
+                       irq &= ~IRQFRAME;
+                       return v;
                case 0x4016:
                        if((mem[p] & 1) != 0)
                                return keys & 1;
@@ -325,6 +402,10 @@ memread(u16int p)
 void
 memwrite(u16int p, u8int v)
 {
+       extern u8int apulen[32];
+       extern u16int dmclen[16];
+       int i;
+
        if(p < 0x2000){
                p &= 0x7FF;
        }else if(p < 0x6000){
@@ -365,15 +446,60 @@ memwrite(u16int p, u8int v)
                        ppuwrite(ppuv, v);
                        incvram();
                        return;
+               case 0x4001:
+               case 0x4005:
+                       i = (p & 0xC) >> 2;
+                       apuctr[i+8] |= 0x80;
+                       break;
+               case 0x4003:
+               case 0x4007:
+               case 0x400B:
+               case 0x400F:
+                       i = (p & 0xC) >> 2;
+                       if((mem[APUSTATUS] & (1<<i)) != 0){
+                               apuctr[i] = apulen[v >> 3];
+                               apuctr[10] |= (1<<i);
+                       }
+                       break;
+               case DMCCTRL:
+                       if((v & 0x80) == 0)
+                               irq &= ~IRQDMC;
+                       dmcfreq = 12 * dmclen[v & 0xf];
+                       break;
+               case DMCBUF:
+                       v &= ~0x80;
+                       break;
                case 0x4014:
                        memcpy(oam, mem + (v<<8), sizeof(oam));
                        return;
+               case APUSTATUS:
+                       for(i = 0; i < 4; i++)
+                               if((v & (1<<i)) == 0)
+                                       apuctr[i] = 0;
+                       if((v & 0x10) != 0 && dmccnt == 0){
+                               dmcaddr = mem[DMCADDR] * 0x40 + 0xC000;
+                               dmccnt = mem[DMCLEN] * 0x10 + 1;
+                       }
+                       irq &= ~IRQDMC;
+                       break;
                case 0x4016:
                        if((mem[p] & 1) != 0 && (v & 1) == 0)
                                keylatch = keys;
                        break;
+               case APUFRAME:
+                       apuseq = 0;
+                       if((v & 0x80) != 0)
+                               apuclock = APUDIV;
+                       else
+                               apuclock = 0;
+                       if((v & 0x40) != 0)
+                               irq &= ~IRQFRAME;
+                       break;
                }
-       }else if(p >= 0x8000){
+       }else if(p < 0x8000){
+               if(saveclock == 0)
+                       saveclock = SAVEFREQ;
+       }else{
                if(mapper[map] != nil)
                        mapper[map](p, v);
                return;