7 uchar bios[16*KB], wram0[32*KB], wram1[256*KB];
9 u16int pram[512], oam[512];
20 u8int waitst[16] = {5, 5, 5, 5, 3, 5, 5, 9, 8, 10, 10, 14};
24 ARR(wram0), ARR(wram1), ARR(vram), ARR(pram), ARR(oam), ARR(reg),
25 VAR(dmaact), ARR(dmar), ARR(waitst),
31 static int eepromread(void);
32 static void eepromwrite(int);
33 static u8int flashread(u16int);
34 static void flashwrite(u16int, u8int);
37 arread(uchar *c, int n)
43 return c[0] | c[1] << 8;
45 return c[0] | c[1] << 8 | c[2] << 16 | c[3] << 24;
50 arwrite(uchar *c, u32int v, int n)
64 ar16read(u16int *c, int h, int n)
68 return c[0] >> (h << 3);
72 return c[0] | c[1] << 16;
77 ar16write(u16int *c, int h, u32int v, int n)
82 c[0] = c[0] & 0xff | ((u8int)v) << 8;
84 c[0] = c[0] & 0xff00 | (u8int)v;
105 if(ppuy >= 160 && ppuy != 227)
114 case 0x100: case 0x104: case 0x108: case 0x10c:
115 return timerget((a - 0x100) / 4);
124 regwrite16(u32int a, u16int v)
128 static u8int ws0[4] = {5,4,3,9};
140 case IME*2: case IE*2:
144 case DMA0CNTH*2: case DMA1CNTH*2: case DMA2CNTH*2: case DMA3CNTH*2:
145 i = (a - DMA0CNTH*2) / 12;
146 if((v & DMAEN) != 0){
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];
160 case FIFOAH*2: case FIFOBH*2:
161 fifoput(a >> 2 & 1, p[-1] | v << 16);
163 case 0x102: case 0x106: case 0x10a: case 0x10e:
164 timerset((a - 0x102) / 4, v);
167 waitst[3] = waitst[7] = ws0[v & 3];
168 waitst[0] = ws0[v >> 2 & 3];
169 waitst[4] = ((v & 1<<4) == 0) + 2;
170 waitst[1] = ws0[v >> 5 & 3];
171 waitst[5] = (v & 1<<7) == 0 ? 5 : 2;
172 waitst[2] = ws0[v >> 8 & 3];
173 waitst[6] = (v & 1<<10) == 0 ? 9 : 2;
174 for(i = 0; i < 8; i++)
175 waitst[8 + i] = waitst[i] + waitst[i | 4];
185 regwrite(u32int a, u32int v, int n)
196 w = w & 0xff00 | (u8int)v;
198 w = w & 0xff | v << 8;
199 regwrite16(a & ~1, w);
206 regwrite16(a + 2, v >> 16);
215 irq = (reg[IME] & 1) != 0 && (reg[IF] & reg[IE]) != 0;
221 memread(u32int a, int n, int seq)
224 assert((a & n-1) == 0);
228 b = a & sizeof(bios) - 1;
230 return arread(bios + b, n);
232 b = a & sizeof(wram1) - 1;
233 cyc += n > 2 ? 6 : 3;
234 return arread(wram1 + b, n);
236 b = a & sizeof(wram0) - 1;
238 return arread(wram0 + b, n);
241 if(b >= sizeof(reg)) goto fault;
244 return regread(b) | regread(b+2) << 16;
247 return regread(b) >> 8;
249 return regread(b) & 0xff;
252 b = a & sizeof(pram) - 1;
254 return ar16read(pram + b/2, b & 1, n);
260 return arread(vram + b, n);
262 b = a & sizeof(oam) - 1;
264 return ar16read(oam + b/2, b & 1, n);
265 case 8: case 9: case 10: case 11: case 12: case 13:
267 cyc += waitst[(a >> 25) - 4 | seq << 2 | (n > 2) << 3];
273 return arread(rom + b, n);
277 return arread(back + b, n);
284 print("read from %#.8ux (pc=%#.8ux)\n", a, curpc);
290 memwrite(u32int a, u32int v, int n)
293 assert((a & n-1) == 0);
299 b = a & sizeof(wram1) - 1;
300 cyc += n > 2 ? 6 : 3;
301 arwrite(wram1 + b, v, n);
304 b = a & sizeof(wram0) - 1;
306 arwrite(wram0 + b, v, n);
311 if(b == 0x410) return;
312 if(b >= sizeof(reg)) goto fault;
316 b = a & sizeof(pram) - 1;
318 ar16write(pram + b/2, b & 1, v, n);
325 arwrite(vram + b, v, n);
328 b = a & sizeof(oam) - 1;
330 ar16write(oam + b/2, b & 1, v, n);
332 case 8: case 9: case 10: case 11: case 12: case 13:
333 if(backup == EEPROM){
342 arwrite(back + b, v, n);
353 print("write to %#.8ux, value %#.8ux (pc=%#.8ux)\n", a, v, curpc);
361 reg[BG2PA] = reg[BG2PD] = 0x100;
364 eepstart = 0x1000000;
366 eepstart = 0x1ffff00;
381 for(i = 0; i < 4; i++)
382 if((dmaact & 1<<i) != 0)
387 cntp = reg + DMA0CNTH + i * 6;
390 snd = (cnt >> DMAWHEN & 3) == 3 && (i == 1 || i == 2);
392 cnt = cnt & ~(3 << DMADCNT) | DMAFIX << DMADCNT | DMAWIDE;
394 sz = (cnt & DMAWIDE) != 0 ? 4 : 2;
396 dr[DMASRC] &= 0x07FFFFFF;
398 dr[DMASRC] &= 0x0FFFFFFF;
400 dr[DMADST] &= 0x7FFFFFFF;
402 dr[DMADST] &= 0x0FFFFFFF;
403 v = memread(dr[DMASRC] & -sz, sz, 1);
404 memwrite(dr[DMADST] & -sz, v, sz);
405 switch(cnt >> DMADCNT & 3){
406 case DMAINC: case DMAINCREL: dr[DMADST] += sz; break;
407 case DMADEC: dr[DMADST] -= sz; break;
409 switch(cnt >> DMASCNT & 3){
410 case DMAINC: dr[DMASRC] += sz; break;
411 case DMADEC: dr[DMASRC] -= sz; break;
414 dr[DMACNT] = i != 3 ? 0x4000 : 0x10000;
415 if(--dr[DMACNT] == 0){
417 if((cnt & DMAREP) != 0){
418 dr[DMACNT] = cntp[-1];
419 if((cnt >> DMADCNT & 3) == DMAINCREL)
420 dr[DMADST] = cntp[-3] | cntp[-2] << 16;
423 if((cnt & DMAIRQ) != 0)
433 u16int *cntp, cnt, c;
435 cntp = reg + DMA0CNTH;
436 for(i = 0; i < 4; i++, cntp += 6){
438 if((cnt & DMAEN) == 0)
440 c = cnt >> DMAWHEN & 3;
446 dmar[i * 4 + DMACNT] = 4;
451 int eepromstate, eeprompos, eepromaddr;
474 eepromstate = EEPROMCMD;
477 v = eepromdata >> 63;
481 if(++eeprompos == 1000){
482 eepromstate = EEPROMCMD;
499 eepromaddr = eepromaddr << 1 | n;
500 if(++eeprompos >= 2){
501 switch(eepromaddr & 3){
503 eepromstate = EEPROMWRCMD;
506 eepromstate = EEPROMRDCMD;
514 eepromaddr = eepromaddr << 1 | n;
518 eepromaddr = eepromaddr >> 1 & 0x3f;
523 eepromaddr = eepromaddr >> 1 & 0x3fff;
527 if(eepromstate == EEPROMRDCMD){
528 p = back + eepromaddr * 8;
529 eepromdata = p[0] | p[1] << 8 | p[2] << 16 | p[3] << 24 | (u64int)p[4] << 32 |
530 (u64int)p[5] << 40 | (u64int)p[6] << 48 | (u64int)p[7] << 56;
532 eepromstate = EEPROMRDRESP;
537 eepromstate = EEPROMWRDATA;
542 p = back + eepromaddr * 8;
544 p[1] = eepromdata >> 8;
545 p[2] = eepromdata >> 16;
546 p[3] = eepromdata >> 24;
547 p[4] = eepromdata >> 32;
548 p[5] = eepromdata >> 40;
549 p[6] = eepromdata >> 48;
550 p[7] = eepromdata >> 56;
551 eepromstate = EEPROMWRRESP;
556 eepromdata = eepromdata << 1 | n;
562 int flashstate, flashmode, flashbank;
578 if((flashmode & FLASHID) != 0)
579 return (a & 1) != 0 ? 0xd4 : 0xbf;
580 return back[(flashbank << 16) + a];
584 flashwrite(u16int a, u8int v)
590 if(a == 0x5555 && v == 0xaa)
591 flashstate = FLASHCMD1;
594 if(a == 0x2aaa && v == 0x55)
595 flashstate = FLASHCMD2;
597 flashstate = FLASHCMD0;
600 flashstate = FLASHCMD0;
601 erase = flashmode & FLASHERASE;
602 flashmode &= ~FLASHERASE;
604 case 0x90: flashmode |= FLASHID; break;
605 case 0xF0: flashmode &= ~FLASHID; break;
606 case 0x80: flashmode |= FLASHERASE; break;
609 memset(back, 0xff, nback);
615 memset(back + (a & 0xf000) + (flashbank << 16), 0xff, 4096);
621 flashstate = FLASHWRITE;
623 case 0xB0: flashstate = FLASHBANK; break;
625 print("unknown flash cmd %x\n", v);
629 flashbank = v % (nback >> 16);
630 flashstate = FLASHCMD0;
633 back[(flashbank << 16) + a] &= v;
635 flashstate = FLASHCMD0;