1 // This is part of Pico Library
\r
3 // (c) Copyright 2006 notaz, All rights reserved.
\r
4 // Free for non-commercial use.
\r
6 // For commercial use, separate licencing terms must be obtained.
\r
11 // H-counter table for hvcounter reads in 40col mode
\r
12 // based on Gens code
\r
13 const unsigned char hcounts_40[] = {
\r
14 0x07,0x07,0x08,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,
\r
15 0x0e,0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x10,0x11,0x11,0x12,0x12,0x13,0x13,0x13,0x14,
\r
16 0x14,0x15,0x15,0x15,0x16,0x16,0x17,0x17,0x18,0x18,0x18,0x19,0x19,0x1a,0x1a,0x1b,
\r
17 0x1b,0x1b,0x1c,0x1c,0x1d,0x1d,0x1d,0x1e,0x1e,0x1f,0x1f,0x20,0x20,0x20,0x21,0x21,
\r
18 0x22,0x22,0x23,0x23,0x23,0x24,0x24,0x25,0x25,0x25,0x26,0x26,0x27,0x27,0x28,0x28,
\r
19 0x28,0x29,0x29,0x2a,0x2a,0x2a,0x2b,0x2b,0x2c,0x2c,0x2d,0x2d,0x2d,0x2e,0x2e,0x2f,
\r
20 0x2f,0x30,0x30,0x30,0x31,0x31,0x32,0x32,0x32,0x33,0x33,0x34,0x34,0x35,0x35,0x35,
\r
21 0x36,0x36,0x37,0x37,0x38,0x38,0x38,0x39,0x39,0x3a,0x3a,0x3a,0x3b,0x3b,0x3c,0x3c,
\r
22 0x3d,0x3d,0x3d,0x3e,0x3e,0x3f,0x3f,0x3f,0x40,0x40,0x41,0x41,0x42,0x42,0x42,0x43,
\r
23 0x43,0x44,0x44,0x45,0x45,0x45,0x46,0x46,0x47,0x47,0x47,0x48,0x48,0x49,0x49,0x4a,
\r
24 0x4a,0x4a,0x4b,0x4b,0x4c,0x4c,0x4d,0x4d,0x4d,0x4e,0x4e,0x4f,0x4f,0x4f,0x50,0x50,
\r
25 0x51,0x51,0x52,0x52,0x52,0x53,0x53,0x54,0x54,0x55,0x55,0x55,0x56,0x56,0x57,0x57,
\r
26 0x57,0x58,0x58,0x59,0x59,0x5a,0x5a,0x5a,0x5b,0x5b,0x5c,0x5c,0x5c,0x5d,0x5d,0x5e,
\r
27 0x5e,0x5f,0x5f,0x5f,0x60,0x60,0x61,0x61,0x62,0x62,0x62,0x63,0x63,0x64,0x64,0x64,
\r
28 0x65,0x65,0x66,0x66,0x67,0x67,0x67,0x68,0x68,0x69,0x69,0x6a,0x6a,0x6a,0x6b,0x6b,
\r
29 0x6c,0x6c,0x6c,0x6d,0x6d,0x6e,0x6e,0x6f,0x6f,0x6f,0x70,0x70,0x71,0x71,0x71,0x72,
\r
30 0x72,0x73,0x73,0x74,0x74,0x74,0x75,0x75,0x76,0x76,0x77,0x77,0x77,0x78,0x78,0x79,
\r
31 0x79,0x79,0x7a,0x7a,0x7b,0x7b,0x7c,0x7c,0x7c,0x7d,0x7d,0x7e,0x7e,0x7f,0x7f,0x7f,
\r
32 0x80,0x80,0x81,0x81,0x81,0x82,0x82,0x83,0x83,0x84,0x84,0x84,0x85,0x85,0x86,0x86,
\r
33 0x86,0x87,0x87,0x88,0x88,0x89,0x89,0x89,0x8a,0x8a,0x8b,0x8b,0x8c,0x8c,0x8c,0x8d,
\r
34 0x8d,0x8e,0x8e,0x8e,0x8f,0x8f,0x90,0x90,0x91,0x91,0x91,0x92,0x92,0x93,0x93,0x94,
\r
35 0x94,0x94,0x95,0x95,0x96,0x96,0x96,0x97,0x97,0x98,0x98,0x99,0x99,0x99,0x9a,0x9a,
\r
36 0x9b,0x9b,0x9b,0x9c,0x9c,0x9d,0x9d,0x9e,0x9e,0x9e,0x9f,0x9f,0xa0,0xa0,0xa1,0xa1,
\r
37 0xa1,0xa2,0xa2,0xa3,0xa3,0xa3,0xa4,0xa4,0xa5,0xa5,0xa6,0xa6,0xa6,0xa7,0xa7,0xa8,
\r
38 0xa8,0xa9,0xa9,0xa9,0xaa,0xaa,0xab,0xab,0xab,0xac,0xac,0xad,0xad,0xae,0xae,0xae,
\r
39 0xaf,0xaf,0xb0,0xb0,
\r
40 0xe4,0xe4,0xe4,0xe5,0xe5,0xe6,0xe6,0xe6,0xe7,0xe7,0xe8,0xe8,0xe9,0xe9,0xe9,0xea,
\r
41 0xea,0xeb,0xeb,0xeb,0xec,0xec,0xed,0xed,0xee,0xee,0xee,0xef,0xef,0xf0,0xf0,0xf1,
\r
42 0xf1,0xf1,0xf2,0xf2,0xf3,0xf3,0xf3,0xf4,0xf4,0xf5,0xf5,0xf6,0xf6,0xf6,0xf7,0xf7,
\r
43 0xf8,0xf8,0xf9,0xf9,0xf9,0xfa,0xfa,0xfb,0xfb,0xfb,0xfc,0xfc,0xfd,0xfd,0xfe,0xfe,
\r
44 0xfe,0xff,0xff,0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x03,0x04,0x04,0x05,
\r
45 0x05,0x06,0x06,0x06,
\r
46 0x07,0x07,0x08,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,
\r
47 0x0e,0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x10,
\r
50 // H-counter table for hvcounter reads in 32col mode
\r
51 const unsigned char hcounts_32[] = {
\r
52 0x05,0x05,0x05,0x06,0x06,0x07,0x07,0x07,0x08,0x08,0x08,0x09,0x09,0x09,0x0a,0x0a,
\r
53 0x0a,0x0b,0x0b,0x0b,0x0c,0x0c,0x0c,0x0d,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,0x0f,0x10,
\r
54 0x10,0x10,0x11,0x11,0x11,0x12,0x12,0x12,0x13,0x13,0x13,0x14,0x14,0x14,0x15,0x15,
\r
55 0x15,0x16,0x16,0x17,0x17,0x17,0x18,0x18,0x18,0x19,0x19,0x19,0x1a,0x1a,0x1a,0x1b,
\r
56 0x1b,0x1b,0x1c,0x1c,0x1c,0x1d,0x1d,0x1d,0x1e,0x1e,0x1f,0x1f,0x1f,0x20,0x20,0x20,
\r
57 0x21,0x21,0x21,0x22,0x22,0x22,0x23,0x23,0x23,0x24,0x24,0x24,0x25,0x25,0x26,0x26,
\r
58 0x26,0x27,0x27,0x27,0x28,0x28,0x28,0x29,0x29,0x29,0x2a,0x2a,0x2a,0x2b,0x2b,0x2b,
\r
59 0x2c,0x2c,0x2c,0x2d,0x2d,0x2e,0x2e,0x2e,0x2f,0x2f,0x2f,0x30,0x30,0x30,0x31,0x31,
\r
60 0x31,0x32,0x32,0x32,0x33,0x33,0x33,0x34,0x34,0x34,0x35,0x35,0x36,0x36,0x36,0x37,
\r
61 0x37,0x37,0x38,0x38,0x38,0x39,0x39,0x39,0x3a,0x3a,0x3a,0x3b,0x3b,0x3b,0x3c,0x3c,
\r
62 0x3d,0x3d,0x3d,0x3e,0x3e,0x3e,0x3f,0x3f,0x3f,0x40,0x40,0x40,0x41,0x41,0x41,0x42,
\r
63 0x42,0x42,0x43,0x43,0x43,0x44,0x44,0x45,0x45,0x45,0x46,0x46,0x46,0x47,0x47,0x47,
\r
64 0x48,0x48,0x48,0x49,0x49,0x49,0x4a,0x4a,0x4a,0x4b,0x4b,0x4b,0x4c,0x4c,0x4d,0x4d,
\r
65 0x4d,0x4e,0x4e,0x4e,0x4f,0x4f,0x4f,0x50,0x50,0x50,0x51,0x51,0x51,0x52,0x52,0x52,
\r
66 0x53,0x53,0x53,0x54,0x54,0x55,0x55,0x55,0x56,0x56,0x56,0x57,0x57,0x57,0x58,0x58,
\r
67 0x58,0x59,0x59,0x59,0x5a,0x5a,0x5a,0x5b,0x5b,0x5c,0x5c,0x5c,0x5d,0x5d,0x5d,0x5e,
\r
68 0x5e,0x5e,0x5f,0x5f,0x5f,0x60,0x60,0x60,0x61,0x61,0x61,0x62,0x62,0x62,0x63,0x63,
\r
69 0x64,0x64,0x64,0x65,0x65,0x65,0x66,0x66,0x66,0x67,0x67,0x67,0x68,0x68,0x68,0x69,
\r
70 0x69,0x69,0x6a,0x6a,0x6a,0x6b,0x6b,0x6c,0x6c,0x6c,0x6d,0x6d,0x6d,0x6e,0x6e,0x6e,
\r
71 0x6f,0x6f,0x6f,0x70,0x70,0x70,0x71,0x71,0x71,0x72,0x72,0x72,0x73,0x73,0x74,0x74,
\r
72 0x74,0x75,0x75,0x75,0x76,0x76,0x76,0x77,0x77,0x77,0x78,0x78,0x78,0x79,0x79,0x79,
\r
73 0x7a,0x7a,0x7b,0x7b,0x7b,0x7c,0x7c,0x7c,0x7d,0x7d,0x7d,0x7e,0x7e,0x7e,0x7f,0x7f,
\r
74 0x7f,0x80,0x80,0x80,0x81,0x81,0x81,0x82,0x82,0x83,0x83,0x83,0x84,0x84,0x84,0x85,
\r
75 0x85,0x85,0x86,0x86,0x86,0x87,0x87,0x87,0x88,0x88,0x88,0x89,0x89,0x89,0x8a,0x8a,
\r
76 0x8b,0x8b,0x8b,0x8c,0x8c,0x8c,0x8d,0x8d,0x8d,0x8e,0x8e,0x8e,0x8f,0x8f,0x8f,0x90,
\r
77 0x90,0x90,0x91,0x91,
\r
78 0xe8,0xe8,0xe8,0xe9,0xe9,0xe9,0xea,0xea,0xea,0xeb,0xeb,0xeb,0xec,0xec,0xec,0xed,
\r
79 0xed,0xed,0xee,0xee,0xee,0xef,0xef,0xf0,0xf0,0xf0,0xf1,0xf1,0xf1,0xf2,0xf2,0xf2,
\r
80 0xf3,0xf3,0xf3,0xf4,0xf4,0xf4,0xf5,0xf5,0xf5,0xf6,0xf6,0xf6,0xf7,0xf7,0xf8,0xf8,
\r
81 0xf8,0xf9,0xf9,0xf9,0xfa,0xfa,0xfa,0xfb,0xfb,0xfb,0xfc,0xfc,0xfc,0xfd,0xfd,0xfd,
\r
82 0xfe,0xfe,0xfe,0xff,0xff,0x00,0x00,0x00,0x01,0x01,0x01,0x02,0x02,0x02,0x03,0x03,
\r
83 0x03,0x04,0x04,0x04,
\r
84 0x05,0x05,0x05,0x06,0x06,0x07,0x07,0x07,0x08,0x08,0x08,0x09,0x09,0x09,0x0a,0x0a,
\r
85 0x0a,0x0b,0x0b,0x0b,0x0c,0x0c,0x0c,0x0d,
\r
88 // vcounter values for PicoFrameSimple
\r
89 const unsigned short vcounts[] = {
\r
90 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7,
\r
91 8, 8, 9, 9, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16,
\r
92 16, 17, 17, 18, 18, 19, 19, 20, 21, 21, 22, 22, 23, 23, 24, 24,
\r
93 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 30, 31, 31, 32, 32, 33,
\r
94 33, 34, 34, 35, 35, 36, 36, 37, 37, 38, 38, 39, 39, 40, 40, 41,
\r
95 42, 42, 43, 43, 44, 44, 45, 45, 46, 46, 47, 47, 48, 48, 49, 49,
\r
96 50, 50, 51, 52, 52, 53, 53, 54, 54, 55, 55, 56, 56, 57, 57, 58,
\r
97 58, 59, 59, 60, 60, 61, 62, 62, 63, 63, 64, 64, 65, 65, 66, 66,
\r
98 67, 67, 68, 68, 69, 69, 70, 70, 71, 71, 72, 73, 73, 74, 74, 75,
\r
99 75, 76, 76, 77, 77, 78, 78, 79, 79, 80, 80, 81, 81, 82, 83, 83,
\r
100 84, 84, 85, 85, 86, 86, 87, 87, 88, 88, 89, 89, 90, 90, 91, 91,
\r
101 92, 93, 93, 94, 94, 95, 95, 96, 96, 97, 97, 98, 98, 99, 99,100,
\r
102 100,101,101,102,102,103,104,104,105,105,106,106,107,107,108,108,
\r
103 109,109,110,110,111,111,112,112,113,114,114,115,115,116,116,117,
\r
104 117,118,118,119,119,120,120,121,121,122,122,123,124,124,125,125,
\r
105 126,126,127,127,128,128,129,129,130,130,131,131,132,132,133,133,
\r
106 134,135,135,136,136,137,137,138,138,139,139,140,140,141,141,142,
\r
107 142,143,143,144,145,145,146,146,147,147,148,148,149,149,150,150,
\r
108 151,151,152,152,153,153,154,155,155,156,156,157,157,158,158,159,
\r
109 159,160,160,161,161,162,162,163,163,164,164,165,166,166,167,167,
\r
110 168,168,169,169,170,170,171,171,172,172,173,173,174,174,175,176,
\r
111 176,177,177,178,178,179,179,180,180,181,181,182,182,183,183,184,
\r
112 184,185,186,186,187,187,188,188,189,189,190,190,191,191,192,192,
\r
113 193,193,194,194,195,195,196,197,197,198,198,199,199,200,200,201,
\r
114 201,202,202,203,203,204,204,205,205,206,207,207,208,208,209,209,
\r
115 210,210,211,211,212,212,213,213,214,214,215,215,216,217,217,218,
\r
116 218,219,219,220,220,221,221,222,222,223,223,224,224,225,225,226,
\r
117 226,227,228,228,229,229,230,230,231,231,232,232,233,233,234,234,
\r
118 235,235,236,236,237,238,238,239,239,240,240,241,241,242,242,243,
\r
119 243,244,244,245,245,246,246,247,248,248,249,249,250,250,251,251,
\r
120 252,252,253,253,254,254,255,255,256,256,257,257,258,259,259,260,
\r
121 260,261,261,262,262,263,263,264,264,265,265,266,266,267,267,268,
\r
122 269,269,270,270,271,271,272,272,273,273,274,274,275,275,276,276,
\r
123 277,277,278,279,279,280,280,281,281,282,282,283,283,284,284,285,
\r
124 285,286,286,287,287,288,288,289,290,290,291,291,292,292,293,293,
\r
125 294,294,295,295,296,296,297,297,298,298,299,300,300,301,301,302,
\r
126 302,303,303,304,304,305,305,306,306,307,307,308,308,309,310,310,
\r
131 // rarely used EEPROM SRAM code
\r
132 // known games which use this:
\r
133 // Wonder Boy in Monster World, Megaman - The Wily Wars (X24C01, 128 bytes)
\r
134 // NFL Quarterback Club*, Frank Thomas Big Hurt Baseball (X24C04?)
\r
135 // College Slam, Blockbuster World Video Game Championship II, NBA Jam (X24C04?)
\r
138 // the above sports games use addr 0x200000 for SCL line (handled in Memory.c)
\r
140 unsigned int lastSSRamWrite = 0xffff0000;
\r
142 // sram_reg: LAtd sela (L=pending SCL, A=pending SDA, t=type(1==uses 0x200000 for SCL and 2K bytes),
\r
143 // d=SRAM was detected (header or by access), s=started, e=save is EEPROM, l=old SCL, a=old SDA)
\r
144 void SRAMWriteEEPROM(unsigned int d) // ???? ??la (l=SCL, a=SDA)
\r
146 unsigned int sreg = Pico.m.sram_reg, saddr = Pico.m.sram_addr, scyc = Pico.m.sram_cycle, ssa = Pico.m.sram_slave;
\r
148 //dprintf("[%02x]", d);
\r
149 sreg |= saddr&0xc000; // we store word count in add reg: dw?a aaaa ... (d=word count detected, w=words(0==use 2 words, else 1))
\r
153 // SCL was and is still high..
\r
154 if((sreg & 1) && !(d&1)) {
\r
155 // ..and SDA went low, means it's a start command, so clear internal addr reg and clock counter
\r
156 //dprintf("-start-");
\r
157 if(!(sreg&0x8000) && scyc >= 9) {
\r
158 if(scyc != 28) sreg |= 0x4000; // 1 word
\r
159 //dprintf("detected word count: %i", scyc==28 ? 2 : 1);
\r
165 } else if(!(sreg & 1) && (d&1)) {
\r
166 // SDA went high == stop command
\r
167 //dprintf("-stop-");
\r
171 else if((sreg & 8) && !(sreg & 2) && (d&2)) {
\r
172 // we are started and SCL went high - next cycle
\r
173 scyc++; // pre-increment
\r
176 if((ssa&1) && scyc == 18) {
\r
178 saddr++; // next address in read mode
\r
179 if(sreg&0x4000) saddr&=0xff; else saddr&=0x1fff; // mask
\r
181 else if((sreg&0x4000) && scyc == 27) scyc = 18;
\r
182 else if(scyc == 36) scyc = 27;
\r
187 if(saddr&1) { saddr+=2; saddr&=0xff; } // next addr in read mode
\r
190 //dprintf("scyc: %i", scyc);
\r
192 else if((sreg & 8) && (sreg & 2) && !(d&2)) {
\r
193 // we are started and SCL went low (falling edge)
\r
196 if(scyc == 9 || scyc == 18 || scyc == 27); // ACK cycles
\r
197 else if( (!(sreg&0x4000) && scyc > 27) || ((sreg&0x4000) && scyc > 18) ) {
\r
200 unsigned char *pm=SRam.data+saddr;
\r
201 *pm <<= 1; *pm |= d&1;
\r
202 if(scyc == 26 || scyc == 35) {
\r
203 saddr=(saddr&~0xf)|((saddr+1)&0xf); // only 4 (?) lowest bits are incremented
\r
204 //dprintf("w done: %02x; addr inc: %x", *pm, saddr);
\r
208 } else if(scyc > 9) {
\r
210 // we latch another addr bit
\r
212 if(sreg&0x4000) saddr&=0xff; else saddr&=0x1fff; // mask
\r
214 //if(scyc==17||scyc==26) dprintf("addr reg done: %x", saddr);
\r
219 //if(scyc==8) dprintf("slave done: %x", ssa);
\r
223 if(scyc == 9); // ACK cycle, do nothing
\r
224 else if(scyc > 9) {
\r
227 unsigned char *pm=SRam.data+(saddr>>1);
\r
228 *pm <<= 1; *pm |= d&1;
\r
230 saddr=(saddr&0xf9)|((saddr+2)&6); // only 2 lowest bits are incremented
\r
231 //dprintf("addr inc: %x", saddr>>1);
\r
236 // we latch another addr bit
\r
237 saddr<<=1; saddr|=d&1; saddr&=0xff;
\r
238 //if(scyc==8) dprintf("addr done: %x", saddr>>1);
\r
243 sreg &= ~3; sreg |= d&3; // remember SCL and SDA
\r
244 Pico.m.sram_reg = (unsigned char) sreg;
\r
245 Pico.m.sram_addr = (unsigned short)(saddr|(sreg&0xc000));
\r
246 Pico.m.sram_cycle= (unsigned char) scyc;
\r
247 Pico.m.sram_slave= (unsigned char) ssa;
\r
250 unsigned int SRAMReadEEPROM()
\r
252 unsigned int shift, d=0;
\r
253 unsigned int sreg, saddr, scyc, ssa;
\r
255 // flush last pending write
\r
256 SRAMWriteEEPROM(Pico.m.sram_reg>>6);
\r
258 sreg = Pico.m.sram_reg; saddr = Pico.m.sram_addr&0x1fff; scyc = Pico.m.sram_cycle; ssa = Pico.m.sram_slave;
\r
259 // if(!(sreg & 2) && (sreg&0x80)) scyc++; // take care of raising edge now to compensate lag
\r
261 if(SekCyclesDoneT()-lastSSRamWrite < 46) {
\r
262 // data was just written, there was no time to respond (used by sports games)
\r
264 } else if((sreg & 8) && scyc > 9 && scyc != 18 && scyc != 27) {
\r
265 // started and first command word received
\r
270 //dprintf("read: addr %02x, cycle %i, reg %02x", saddr, scyc, sreg);
\r
271 d = (SRam.data[saddr]>>shift)&1;
\r
276 d = (SRam.data[saddr>>1]>>shift)&1;
\r
280 //else dprintf("r ack");
\r
285 void SRAMUpdPending(unsigned int a, unsigned int d)
\r
287 unsigned int sreg = Pico.m.sram_reg;
\r
289 if(!(a&1)) sreg|=0x20;
\r
291 if(sreg&0x20) { // address through 0x200000
\r
304 Pico.m.sram_reg = (unsigned char) sreg;
\r
308 #ifndef _ASM_MISC_C
\r
309 void memcpy16(unsigned short *dest, unsigned short *src, int count)
\r
316 void memcpy16bswap(unsigned short *dest, void *src, int count)
\r
318 unsigned char *src_ = src;
\r
320 for (; count; count--, src_ += 2)
\r
321 *dest++ = (src_[0] << 8) | src_[1];
\r
325 void memcpy32(int *dest, int *src, int count)
\r
332 void memset32(int *dest, int c, int count)
\r