7 uchar bios[16*KB], wram0[32*KB], wram1[256*KB];
9 u16int pram[512], oam[512];
22 u8int waitst[16] = {5, 5, 5, 5, 3, 5, 5, 9, 8, 10, 10, 14};
26 static int eepromread(void);
27 static void eepromwrite(int);
28 static u8int flashread(u16int);
29 static void flashwrite(u16int, u8int);
32 arread(uchar *c, int n)
38 return c[0] | c[1] << 8;
40 return c[0] | c[1] << 8 | c[2] << 16 | c[3] << 24;
45 arwrite(uchar *c, u32int v, int n)
59 ar16read(u16int *c, int h, int n)
63 return c[0] >> (h << 3);
67 return c[0] | c[1] << 16;
72 ar16write(u16int *c, int h, u32int v, int n)
77 c[0] = c[0] & 0xff | ((u8int)v) << 8;
79 c[0] = c[0] & 0xff00 | (u8int)v;
100 if(ppuy >= 160 && ppuy != 227)
109 case 0x100: case 0x104: case 0x108: case 0x10c:
110 return tim[(a - 0x100) / 4];
119 regwrite16(u32int a, u16int v)
123 static u8int ws0[4] = {5,4,3,9};
135 bldb = v >> 8 & 0x1f;
144 case DMA0CNTH*2: case DMA1CNTH*2: case DMA2CNTH*2: case DMA3CNTH*2:
145 if((*p & DMAEN) == 0 && (v & DMAEN) != 0){
146 i = (a - DMA0CNTH*2) / 12;
147 if((v >> DMAWHEN & 3) == 0)
149 if(i == 3 && (v >> DMAWHEN & 3) == 3)
150 print("DMA video capture mode\n");
151 dmar[4*i + DMASRC] = p[-5] | p[-4] << 16;
152 dmar[4*i + DMADST] = p[-3] | p[-2] << 16;
153 dmar[4*i + DMACNT] = p[-1];
156 case 0x102: case 0x106: case 0x10a: case 0x10e:
157 if((*p & 1<<7) == 0 && (v & 1<<7) != 0)
158 tim[(a-0x102)/4] = p[-1];
160 case IME*2: case IE*2:
164 waitst[3] = waitst[7] = ws0[v & 3];
165 waitst[0] = ws0[v >> 2 & 3];
166 waitst[4] = ((v & 1<<4) == 0) + 2;
167 waitst[1] = ws0[v >> 5 & 3];
168 waitst[5] = (v & 1<<7) == 0 ? 5 : 2;
169 waitst[2] = ws0[v >> 8 & 3];
170 waitst[6] = (v & 1<<10) == 0 ? 9 : 2;
171 for(i = 0; i < 8; i++)
172 waitst[8 + i] = waitst[i] + waitst[i | 4];
182 regwrite(u32int a, u32int v, int n)
193 w = w & 0xff00 | (u8int)v;
195 w = w & 0xff | v << 8;
200 sysfatal("unaligned register access");
205 sysfatal("unaligned register access");
207 regwrite16(a + 2, v >> 16);
216 irq = (reg[IME] & 1) != 0 && (reg[IF] & reg[IE]) != 0;
222 memread(u32int a, int n, int seq)
225 assert((a & n-1) == 0);
229 b = a & sizeof(bios) - 1;
231 return arread(bios + b, n);
233 b = a & sizeof(wram1) - 1;
234 cyc += n > 2 ? 6 : 3;
235 return arread(wram1 + b, n);
237 b = a & sizeof(wram0) - 1;
239 return arread(wram0 + b, n);
242 if(b >= sizeof(reg)) goto fault;
245 return regread(b) | regread(b+2) << 16;
248 b = a & sizeof(pram) - 1;
250 return ar16read(pram + b/2, b & 1, n);
256 return arread(vram + b, n);
258 b = a & sizeof(oam) - 1;
260 return ar16read(oam + b/2, b & 1, n);
261 case 8: case 9: case 10: case 11: case 12: case 13:
263 cyc += waitst[(a >> 25) - 4 | seq << 2 | (n > 2) << 3];
265 if(backup == EEPROM && b >= 0x1000000 && (nrom < 16*KB*KB || b >= 0x1ffff00))
269 return arread(rom + b, n);
273 return arread(back + b, n);
280 sysfatal("read from %#.8ux (pc=%#.8ux)", a, curpc);
286 memwrite(u32int a, u32int v, int n)
289 assert((a & n-1) == 0);
295 b = a & sizeof(wram1) - 1;
296 cyc += n > 2 ? 6 : 3;
297 arwrite(wram1 + b, v, n);
300 b = a & sizeof(wram0) - 1;
302 arwrite(wram0 + b, v, n);
307 if(b == 0x410) return;
308 if(b >= sizeof(reg)) goto fault;
312 b = a & sizeof(pram) - 1;
314 ar16write(pram + b/2, b & 1, v, n);
321 arwrite(vram + b, v, n);
324 b = a & sizeof(oam) - 1;
326 ar16write(oam + b/2, b & 1, v, n);
328 case 8: case 9: case 10: case 11: case 12: case 13:
329 if(backup == EEPROM){
331 if(b >= 0x1000000 && (nrom < 16*KB*KB || b >= 0x1ffff00))
338 arwrite(back + b, v, n);
349 sysfatal("write to %#.8ux, value %#.8ux (pc=%#.8ux)", a, v, curpc);
369 for(i = 0; i < 4; i++){
370 c = reg[0x102/2 + i*2];
376 if((timerclock & 63) != 0)
380 if((timerclock & 255) != 0)
384 if((timerclock & 1023) != 0)
391 if(carry = tim[i] >= nt){
392 tim[i] += reg[0x100/2 + i*2];
413 for(i = 0; i < 4; i++)
414 if((dmaact & 1<<i) != 0)
419 cntp = reg + DMA0CNTH + i * 6;
423 sz = (cnt & DMAWIDE) != 0 ? 4 : 2;
425 dr[DMASRC] &= 0x07FFFFFF;
427 dr[DMASRC] &= 0x0FFFFFFF;
429 dr[DMADST] &= 0x7FFFFFFF;
431 dr[DMADST] &= 0x0FFFFFFF;
432 v = memread(dr[DMASRC] & -sz, sz, 1);
433 memwrite(dr[DMADST] & -sz, v, sz);
434 switch(cnt >> DMADCNT & 3){
435 case DMAINC: case DMAINCREL: dr[DMADST] += sz; break;
436 case DMADEC: dr[DMADST] -= sz; break;
438 switch(cnt >> DMASCNT & 3){
439 case DMAINC: dr[DMASRC] += sz; break;
440 case DMADEC: dr[DMASRC] -= sz; break;
443 dr[DMACNT] = i != 3 ? 0x4000 : 0x10000;
444 if(--dr[DMACNT] == 0){
446 if((cnt & DMAREP) != 0){
447 dmar[DMACNT] = cntp[-1];
448 if((cnt >> DMADCNT & 3) == DMAINCREL)
449 dmar[DMADST] = cntp[-3] | cntp[-2] << 16;
452 if((cnt & DMAIRQ) != 0)
462 u16int *cntp, cnt, c;
464 cntp = reg + DMA0CNTH;
465 for(i = 0; i < 3; i++, cntp += 6){
467 if((cnt & DMAEN) == 0)
469 c = cnt >> DMAWHEN & 3;
477 int eepromstate, eeprompos, eepromaddr;
500 eepromstate = EEPROMCMD;
503 v = eepromdata >> 63;
507 if(++eeprompos == 1000){
508 eepromstate = EEPROMCMD;
525 eepromaddr = eepromaddr << 1 | n;
526 if(++eeprompos >= 2){
527 switch(eepromaddr & 3){
529 eepromstate = EEPROMWRCMD;
532 eepromstate = EEPROMRDCMD;
540 eepromaddr = eepromaddr << 1 | n;
544 eepromaddr = eepromaddr >> 1 & 0x3f;
549 eepromaddr = eepromaddr >> 1 & 0x3fff;
553 if(eepromstate == EEPROMRDCMD){
554 p = back + eepromaddr * 8;
555 eepromdata = p[0] | p[1] << 8 | p[2] << 16 | p[3] << 24 | (u64int)p[4] << 32 |
556 (u64int)p[5] << 40 | (u64int)p[6] << 48 | (u64int)p[7] << 56;
558 eepromstate = EEPROMRDRESP;
563 eepromstate = EEPROMWRDATA;
568 p = back + eepromaddr * 8;
570 p[1] = eepromdata >> 8;
571 p[2] = eepromdata >> 16;
572 p[3] = eepromdata >> 24;
573 p[4] = eepromdata >> 32;
574 p[5] = eepromdata >> 40;
575 p[6] = eepromdata >> 48;
576 p[7] = eepromdata >> 56;
577 eepromstate = EEPROMWRRESP;
582 eepromdata = eepromdata << 1 | n;
588 int flashstate, flashmode, flashbank;
604 if((flashmode & FLASHID) != 0)
605 return (a & 1) != 0 ? 0xd4 : 0xbf;
606 return back[(flashbank << 16) + a];
610 flashwrite(u16int a, u8int v)
616 if(a == 0x5555 && v == 0xaa)
617 flashstate = FLASHCMD1;
620 if(a == 0x2aaa && v == 0x55)
621 flashstate = FLASHCMD2;
623 flashstate = FLASHCMD0;
626 flashstate = FLASHCMD0;
627 erase = flashmode & FLASHERASE;
628 flashmode &= ~FLASHERASE;
630 case 0x90: flashmode |= FLASHID; break;
631 case 0xF0: flashmode &= ~FLASHID; break;
632 case 0x80: flashmode |= FLASHERASE; break;
635 memset(back, 0xff, nback);
641 memset(back + (a & 0xf000) + (flashbank << 16), 0xff, 4096);
647 flashstate = FLASHWRITE;
649 case 0xB0: flashstate = FLASHBANK; break;
651 print("unknown flash cmd %x\n", v);
655 flashbank = v % (nback >> 16);
656 flashstate = FLASHCMD0;
659 back[(flashbank << 16) + a] &= v;
661 flashstate = FLASHCMD0;