dualcore integration in famc, bram cart C code, psp bugfixes
[picodrive.git] / Pico / Misc.c
... / ...
CommitLineData
1// This is part of Pico Library\r
2\r
3// (c) Copyright 2006 notaz, All rights reserved.\r
4// Free for non-commercial use.\r
5\r
6// For commercial use, separate licencing terms must be obtained.\r
7\r
8\r
9#include "PicoInt.h"\r
10\r
11// H-counter table for hvcounter reads in 40col mode\r
12// based on Gens code\r
13const unsigned char hcounts_40[] = {\r
140x07,0x07,0x08,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,\r
150x0e,0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x10,0x11,0x11,0x12,0x12,0x13,0x13,0x13,0x14,\r
160x14,0x15,0x15,0x15,0x16,0x16,0x17,0x17,0x18,0x18,0x18,0x19,0x19,0x1a,0x1a,0x1b,\r
170x1b,0x1b,0x1c,0x1c,0x1d,0x1d,0x1d,0x1e,0x1e,0x1f,0x1f,0x20,0x20,0x20,0x21,0x21,\r
180x22,0x22,0x23,0x23,0x23,0x24,0x24,0x25,0x25,0x25,0x26,0x26,0x27,0x27,0x28,0x28,\r
190x28,0x29,0x29,0x2a,0x2a,0x2a,0x2b,0x2b,0x2c,0x2c,0x2d,0x2d,0x2d,0x2e,0x2e,0x2f,\r
200x2f,0x30,0x30,0x30,0x31,0x31,0x32,0x32,0x32,0x33,0x33,0x34,0x34,0x35,0x35,0x35,\r
210x36,0x36,0x37,0x37,0x38,0x38,0x38,0x39,0x39,0x3a,0x3a,0x3a,0x3b,0x3b,0x3c,0x3c,\r
220x3d,0x3d,0x3d,0x3e,0x3e,0x3f,0x3f,0x3f,0x40,0x40,0x41,0x41,0x42,0x42,0x42,0x43,\r
230x43,0x44,0x44,0x45,0x45,0x45,0x46,0x46,0x47,0x47,0x47,0x48,0x48,0x49,0x49,0x4a,\r
240x4a,0x4a,0x4b,0x4b,0x4c,0x4c,0x4d,0x4d,0x4d,0x4e,0x4e,0x4f,0x4f,0x4f,0x50,0x50,\r
250x51,0x51,0x52,0x52,0x52,0x53,0x53,0x54,0x54,0x55,0x55,0x55,0x56,0x56,0x57,0x57,\r
260x57,0x58,0x58,0x59,0x59,0x5a,0x5a,0x5a,0x5b,0x5b,0x5c,0x5c,0x5c,0x5d,0x5d,0x5e,\r
270x5e,0x5f,0x5f,0x5f,0x60,0x60,0x61,0x61,0x62,0x62,0x62,0x63,0x63,0x64,0x64,0x64,\r
280x65,0x65,0x66,0x66,0x67,0x67,0x67,0x68,0x68,0x69,0x69,0x6a,0x6a,0x6a,0x6b,0x6b,\r
290x6c,0x6c,0x6c,0x6d,0x6d,0x6e,0x6e,0x6f,0x6f,0x6f,0x70,0x70,0x71,0x71,0x71,0x72,\r
300x72,0x73,0x73,0x74,0x74,0x74,0x75,0x75,0x76,0x76,0x77,0x77,0x77,0x78,0x78,0x79,\r
310x79,0x79,0x7a,0x7a,0x7b,0x7b,0x7c,0x7c,0x7c,0x7d,0x7d,0x7e,0x7e,0x7f,0x7f,0x7f,\r
320x80,0x80,0x81,0x81,0x81,0x82,0x82,0x83,0x83,0x84,0x84,0x84,0x85,0x85,0x86,0x86,\r
330x86,0x87,0x87,0x88,0x88,0x89,0x89,0x89,0x8a,0x8a,0x8b,0x8b,0x8c,0x8c,0x8c,0x8d,\r
340x8d,0x8e,0x8e,0x8e,0x8f,0x8f,0x90,0x90,0x91,0x91,0x91,0x92,0x92,0x93,0x93,0x94,\r
350x94,0x94,0x95,0x95,0x96,0x96,0x96,0x97,0x97,0x98,0x98,0x99,0x99,0x99,0x9a,0x9a,\r
360x9b,0x9b,0x9b,0x9c,0x9c,0x9d,0x9d,0x9e,0x9e,0x9e,0x9f,0x9f,0xa0,0xa0,0xa1,0xa1,\r
370xa1,0xa2,0xa2,0xa3,0xa3,0xa3,0xa4,0xa4,0xa5,0xa5,0xa6,0xa6,0xa6,0xa7,0xa7,0xa8,\r
380xa8,0xa9,0xa9,0xa9,0xaa,0xaa,0xab,0xab,0xab,0xac,0xac,0xad,0xad,0xae,0xae,0xae,\r
390xaf,0xaf,0xb0,0xb0,\r
400xe4,0xe4,0xe4,0xe5,0xe5,0xe6,0xe6,0xe6,0xe7,0xe7,0xe8,0xe8,0xe9,0xe9,0xe9,0xea,\r
410xea,0xeb,0xeb,0xeb,0xec,0xec,0xed,0xed,0xee,0xee,0xee,0xef,0xef,0xf0,0xf0,0xf1,\r
420xf1,0xf1,0xf2,0xf2,0xf3,0xf3,0xf3,0xf4,0xf4,0xf5,0xf5,0xf6,0xf6,0xf6,0xf7,0xf7,\r
430xf8,0xf8,0xf9,0xf9,0xf9,0xfa,0xfa,0xfb,0xfb,0xfb,0xfc,0xfc,0xfd,0xfd,0xfe,0xfe,\r
440xfe,0xff,0xff,0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x03,0x04,0x04,0x05,\r
450x05,0x06,0x06,0x06,\r
460x07,0x07,0x08,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,\r
470x0e,0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x10,\r
48};\r
49\r
50// H-counter table for hvcounter reads in 32col mode\r
51const unsigned char hcounts_32[] = {\r
520x05,0x05,0x05,0x06,0x06,0x07,0x07,0x07,0x08,0x08,0x08,0x09,0x09,0x09,0x0a,0x0a,\r
530x0a,0x0b,0x0b,0x0b,0x0c,0x0c,0x0c,0x0d,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,0x0f,0x10,\r
540x10,0x10,0x11,0x11,0x11,0x12,0x12,0x12,0x13,0x13,0x13,0x14,0x14,0x14,0x15,0x15,\r
550x15,0x16,0x16,0x17,0x17,0x17,0x18,0x18,0x18,0x19,0x19,0x19,0x1a,0x1a,0x1a,0x1b,\r
560x1b,0x1b,0x1c,0x1c,0x1c,0x1d,0x1d,0x1d,0x1e,0x1e,0x1f,0x1f,0x1f,0x20,0x20,0x20,\r
570x21,0x21,0x21,0x22,0x22,0x22,0x23,0x23,0x23,0x24,0x24,0x24,0x25,0x25,0x26,0x26,\r
580x26,0x27,0x27,0x27,0x28,0x28,0x28,0x29,0x29,0x29,0x2a,0x2a,0x2a,0x2b,0x2b,0x2b,\r
590x2c,0x2c,0x2c,0x2d,0x2d,0x2e,0x2e,0x2e,0x2f,0x2f,0x2f,0x30,0x30,0x30,0x31,0x31,\r
600x31,0x32,0x32,0x32,0x33,0x33,0x33,0x34,0x34,0x34,0x35,0x35,0x36,0x36,0x36,0x37,\r
610x37,0x37,0x38,0x38,0x38,0x39,0x39,0x39,0x3a,0x3a,0x3a,0x3b,0x3b,0x3b,0x3c,0x3c,\r
620x3d,0x3d,0x3d,0x3e,0x3e,0x3e,0x3f,0x3f,0x3f,0x40,0x40,0x40,0x41,0x41,0x41,0x42,\r
630x42,0x42,0x43,0x43,0x43,0x44,0x44,0x45,0x45,0x45,0x46,0x46,0x46,0x47,0x47,0x47,\r
640x48,0x48,0x48,0x49,0x49,0x49,0x4a,0x4a,0x4a,0x4b,0x4b,0x4b,0x4c,0x4c,0x4d,0x4d,\r
650x4d,0x4e,0x4e,0x4e,0x4f,0x4f,0x4f,0x50,0x50,0x50,0x51,0x51,0x51,0x52,0x52,0x52,\r
660x53,0x53,0x53,0x54,0x54,0x55,0x55,0x55,0x56,0x56,0x56,0x57,0x57,0x57,0x58,0x58,\r
670x58,0x59,0x59,0x59,0x5a,0x5a,0x5a,0x5b,0x5b,0x5c,0x5c,0x5c,0x5d,0x5d,0x5d,0x5e,\r
680x5e,0x5e,0x5f,0x5f,0x5f,0x60,0x60,0x60,0x61,0x61,0x61,0x62,0x62,0x62,0x63,0x63,\r
690x64,0x64,0x64,0x65,0x65,0x65,0x66,0x66,0x66,0x67,0x67,0x67,0x68,0x68,0x68,0x69,\r
700x69,0x69,0x6a,0x6a,0x6a,0x6b,0x6b,0x6c,0x6c,0x6c,0x6d,0x6d,0x6d,0x6e,0x6e,0x6e,\r
710x6f,0x6f,0x6f,0x70,0x70,0x70,0x71,0x71,0x71,0x72,0x72,0x72,0x73,0x73,0x74,0x74,\r
720x74,0x75,0x75,0x75,0x76,0x76,0x76,0x77,0x77,0x77,0x78,0x78,0x78,0x79,0x79,0x79,\r
730x7a,0x7a,0x7b,0x7b,0x7b,0x7c,0x7c,0x7c,0x7d,0x7d,0x7d,0x7e,0x7e,0x7e,0x7f,0x7f,\r
740x7f,0x80,0x80,0x80,0x81,0x81,0x81,0x82,0x82,0x83,0x83,0x83,0x84,0x84,0x84,0x85,\r
750x85,0x85,0x86,0x86,0x86,0x87,0x87,0x87,0x88,0x88,0x88,0x89,0x89,0x89,0x8a,0x8a,\r
760x8b,0x8b,0x8b,0x8c,0x8c,0x8c,0x8d,0x8d,0x8d,0x8e,0x8e,0x8e,0x8f,0x8f,0x8f,0x90,\r
770x90,0x90,0x91,0x91,\r
780xe8,0xe8,0xe8,0xe9,0xe9,0xe9,0xea,0xea,0xea,0xeb,0xeb,0xeb,0xec,0xec,0xec,0xed,\r
790xed,0xed,0xee,0xee,0xee,0xef,0xef,0xf0,0xf0,0xf0,0xf1,0xf1,0xf1,0xf2,0xf2,0xf2,\r
800xf3,0xf3,0xf3,0xf4,0xf4,0xf4,0xf5,0xf5,0xf5,0xf6,0xf6,0xf6,0xf7,0xf7,0xf8,0xf8,\r
810xf8,0xf9,0xf9,0xf9,0xfa,0xfa,0xfa,0xfb,0xfb,0xfb,0xfc,0xfc,0xfc,0xfd,0xfd,0xfd,\r
820xfe,0xfe,0xfe,0xff,0xff,0x00,0x00,0x00,0x01,0x01,0x01,0x02,0x02,0x02,0x03,0x03,\r
830x03,0x04,0x04,0x04,\r
840x05,0x05,0x05,0x06,0x06,0x07,0x07,0x07,0x08,0x08,0x08,0x09,0x09,0x09,0x0a,0x0a,\r
850x0a,0x0b,0x0b,0x0b,0x0c,0x0c,0x0c,0x0d,\r
86};\r
87\r
88// vcounter values for PicoFrameSimple\r
89const 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
102100,101,101,102,102,103,104,104,105,105,106,106,107,107,108,108,\r
103109,109,110,110,111,111,112,112,113,114,114,115,115,116,116,117,\r
104117,118,118,119,119,120,120,121,121,122,122,123,124,124,125,125,\r
105126,126,127,127,128,128,129,129,130,130,131,131,132,132,133,133,\r
106134,135,135,136,136,137,137,138,138,139,139,140,140,141,141,142,\r
107142,143,143,144,145,145,146,146,147,147,148,148,149,149,150,150,\r
108151,151,152,152,153,153,154,155,155,156,156,157,157,158,158,159,\r
109159,160,160,161,161,162,162,163,163,164,164,165,166,166,167,167,\r
110168,168,169,169,170,170,171,171,172,172,173,173,174,174,175,176,\r
111176,177,177,178,178,179,179,180,180,181,181,182,182,183,183,184,\r
112184,185,186,186,187,187,188,188,189,189,190,190,191,191,192,192,\r
113193,193,194,194,195,195,196,197,197,198,198,199,199,200,200,201,\r
114201,202,202,203,203,204,204,205,205,206,207,207,208,208,209,209,\r
115210,210,211,211,212,212,213,213,214,214,215,215,216,217,217,218,\r
116218,219,219,220,220,221,221,222,222,223,223,224,224,225,225,226,\r
117226,227,228,228,229,229,230,230,231,231,232,232,233,233,234,234,\r
118235,235,236,236,237,238,238,239,239,240,240,241,241,242,242,243,\r
119243,244,244,245,245,246,246,247,248,248,249,249,250,250,251,251,\r
120252,252,253,253,254,254,255,255,256,256,257,257,258,259,259,260,\r
121260,261,261,262,262,263,263,264,264,265,265,266,266,267,267,268,\r
122269,269,270,270,271,271,272,272,273,273,274,274,275,275,276,276,\r
123277,277,278,279,279,280,280,281,281,282,282,283,283,284,284,285,\r
124285,286,286,287,287,288,288,289,290,290,291,291,292,292,293,293,\r
125294,294,295,295,296,296,297,297,298,298,299,300,300,301,301,302,\r
126302,303,303,304,304,305,305,306,306,307,307,308,308,309,310,310,\r
127311,311,311,311,\r
128};\r
129\r
130\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\r
135// (see Genesis Plus for Wii/GC code and docs for info,\r
136// full game list and better code).\r
137\r
138unsigned int lastSSRamWrite = 0xffff0000;\r
139\r
140// sram_reg: LAtd sela (L=pending SCL, A=pending SDA, t=(unused),\r
141// d=SRAM was detected (header or by access), s=started, e=save is EEPROM, l=old SCL, a=old SDA)\r
142PICO_INTERNAL void SRAMWriteEEPROM(unsigned int d) // ???? ??la (l=SCL, a=SDA)\r
143{\r
144 unsigned int sreg = Pico.m.sram_reg, saddr = Pico.m.eeprom_addr, scyc = Pico.m.eeprom_cycle, ssa = Pico.m.eeprom_slave;\r
145\r
146 elprintf(EL_EEPROM, "eeprom: scl/sda: %i/%i -> %i/%i, newtime=%i", (sreg&2)>>1, sreg&1,\r
147 (d&2)>>1, d&1, SekCyclesDoneT()-lastSSRamWrite);\r
148 saddr&=0x1fff;\r
149\r
150 if(sreg & d & 2) {\r
151 // SCL was and is still high..\r
152 if((sreg & 1) && !(d&1)) {\r
153 // ..and SDA went low, means it's a start command, so clear internal addr reg and clock counter\r
154 elprintf(EL_EEPROM, "eeprom: -start-");\r
155 //saddr = 0;\r
156 scyc = 0;\r
157 sreg |= 8;\r
158 } else if(!(sreg & 1) && (d&1)) {\r
159 // SDA went high == stop command\r
160 elprintf(EL_EEPROM, "eeprom: -stop-");\r
161 sreg &= ~8;\r
162 }\r
163 }\r
164 else if((sreg & 8) && !(sreg & 2) && (d&2))\r
165 {\r
166 // we are started and SCL went high - next cycle\r
167 scyc++; // pre-increment\r
168 if(SRam.eeprom_type) {\r
169 // X24C02+\r
170 if((ssa&1) && scyc == 18) {\r
171 scyc = 9;\r
172 saddr++; // next address in read mode\r
173 /*if(SRam.eeprom_type==2) saddr&=0xff; else*/ saddr&=0x1fff; // mask\r
174 }\r
175 else if(SRam.eeprom_type == 2 && scyc == 27) scyc = 18;\r
176 else if(scyc == 36) scyc = 27;\r
177 } else {\r
178 // X24C01\r
179 if(scyc == 18) {\r
180 scyc = 9; // wrap\r
181 if(saddr&1) { saddr+=2; saddr&=0xff; } // next addr in read mode\r
182 }\r
183 }\r
184 elprintf(EL_EEPROM, "eeprom: scyc: %i", scyc);\r
185 }\r
186 else if((sreg & 8) && (sreg & 2) && !(d&2))\r
187 {\r
188 // we are started and SCL went low (falling edge)\r
189 if(SRam.eeprom_type) {\r
190 // X24C02+\r
191 if(scyc == 9 || scyc == 18 || scyc == 27); // ACK cycles\r
192 else if( (SRam.eeprom_type == 3 && scyc > 27) || (SRam.eeprom_type == 2 && scyc > 18) ) {\r
193 if(!(ssa&1)) {\r
194 // data write\r
195 unsigned char *pm=SRam.data+saddr;\r
196 *pm <<= 1; *pm |= d&1;\r
197 if(scyc == 26 || scyc == 35) {\r
198 saddr=(saddr&~0xf)|((saddr+1)&0xf); // only 4 (?) lowest bits are incremented\r
199 elprintf(EL_EEPROM, "eeprom: write done, addr inc to: %x, last byte=%02x", saddr, *pm);\r
200 }\r
201 SRam.changed = 1;\r
202 }\r
203 } else if(scyc > 9) {\r
204 if(!(ssa&1)) {\r
205 // we latch another addr bit\r
206 saddr<<=1;\r
207 if(SRam.eeprom_type == 2) saddr&=0xff; else saddr&=0x1fff; // mask\r
208 saddr|=d&1;\r
209 if(scyc==17||scyc==26) {\r
210 elprintf(EL_EEPROM, "eeprom: addr reg done: %x", saddr);\r
211 if(scyc==17&&SRam.eeprom_type==2) { saddr&=0xff; saddr|=(ssa<<7)&0x700; } // add device bits too\r
212 }\r
213 }\r
214 } else {\r
215 // slave address\r
216 ssa<<=1; ssa|=d&1;\r
217 if(scyc==8) elprintf(EL_EEPROM, "eeprom: slave done: %x", ssa);\r
218 }\r
219 } else {\r
220 // X24C01\r
221 if(scyc == 9); // ACK cycle, do nothing\r
222 else if(scyc > 9) {\r
223 if(!(saddr&1)) {\r
224 // data write\r
225 unsigned char *pm=SRam.data+(saddr>>1);\r
226 *pm <<= 1; *pm |= d&1;\r
227 if(scyc == 17) {\r
228 saddr=(saddr&0xf9)|((saddr+2)&6); // only 2 lowest bits are incremented\r
229 elprintf(EL_EEPROM, "eeprom: write done, addr inc to: %x, last byte=%02x", saddr>>1, *pm);\r
230 }\r
231 SRam.changed = 1;\r
232 }\r
233 } else {\r
234 // we latch another addr bit\r
235 saddr<<=1; saddr|=d&1; saddr&=0xff;\r
236 if(scyc==8) elprintf(EL_EEPROM, "eeprom: addr done: %x", saddr>>1);\r
237 }\r
238 }\r
239 }\r
240\r
241 sreg &= ~3; sreg |= d&3; // remember SCL and SDA\r
242 Pico.m.sram_reg = (unsigned char) sreg;\r
243 Pico.m.eeprom_cycle= (unsigned char) scyc;\r
244 Pico.m.eeprom_slave= (unsigned char) ssa;\r
245 Pico.m.eeprom_addr = (unsigned short)saddr;\r
246}\r
247\r
248PICO_INTERNAL_ASM unsigned int SRAMReadEEPROM(void)\r
249{\r
250 unsigned int shift, d;\r
251 unsigned int sreg, saddr, scyc, ssa, interval;\r
252\r
253 // flush last pending write\r
254 SRAMWriteEEPROM(Pico.m.sram_reg>>6);\r
255\r
256 sreg = Pico.m.sram_reg; saddr = Pico.m.eeprom_addr&0x1fff; scyc = Pico.m.eeprom_cycle; ssa = Pico.m.eeprom_slave;\r
257 interval = SekCyclesDoneT()-lastSSRamWrite;\r
258 d = (sreg>>6)&1; // use SDA as "open bus"\r
259\r
260 // NBA Jam is nasty enough to read <before> raising the SCL and starting the new cycle.\r
261 // this is probably valid because data changes occur while SCL is low and data can be read\r
262 // before it's actual cycle begins.\r
263 if (!(sreg&0x80) && interval >= 24) {\r
264 elprintf(EL_EEPROM, "eeprom: early read, cycles=%i", interval);\r
265 scyc++;\r
266 }\r
267\r
268 if (!(sreg & 8)); // not started, use open bus\r
269 else if (scyc == 9 || scyc == 18 || scyc == 27) {\r
270 elprintf(EL_EEPROM, "eeprom: r ack");\r
271 d = 0;\r
272 } else if (scyc > 9 && scyc < 18) {\r
273 // started and first command word received\r
274 shift = 17-scyc;\r
275 if (SRam.eeprom_type) {\r
276 // X24C02+\r
277 if (ssa&1) {\r
278 elprintf(EL_EEPROM, "eeprom: read: addr %02x, cycle %i, reg %02x", saddr, scyc, sreg);\r
279 if (shift==0) elprintf(EL_EEPROM, "eeprom: read done, byte %02x", SRam.data[saddr]);\r
280 d = (SRam.data[saddr]>>shift)&1;\r
281 }\r
282 } else {\r
283 // X24C01\r
284 if (saddr&1) {\r
285 elprintf(EL_EEPROM, "eeprom: read: addr %02x, cycle %i, reg %02x", saddr>>1, scyc, sreg);\r
286 if (shift==0) elprintf(EL_EEPROM, "eeprom: read done, byte %02x", SRam.data[saddr>>1]);\r
287 d = (SRam.data[saddr>>1]>>shift)&1;\r
288 }\r
289 }\r
290 }\r
291\r
292 return (d << SRam.eeprom_bit_out);\r
293}\r
294\r
295PICO_INTERNAL void SRAMUpdPending(unsigned int a, unsigned int d)\r
296{\r
297 unsigned int d1, sreg = Pico.m.sram_reg;\r
298\r
299 if (!((SRam.eeprom_abits^a)&1))\r
300 {\r
301 // SCL\r
302 sreg &= ~0x80;\r
303 d1 = (d >> SRam.eeprom_bit_cl) & 1;\r
304 sreg |= d1<<7;\r
305 }\r
306 if (!(((SRam.eeprom_abits>>1)^a)&1))\r
307 {\r
308 // SDA in\r
309 sreg &= ~0x40;\r
310 d1 = (d >> SRam.eeprom_bit_in) & 1;\r
311 sreg |= d1<<6;\r
312 }\r
313\r
314 Pico.m.sram_reg = (unsigned char) sreg;\r
315}\r
316\r
317\r
318#ifndef _ASM_MISC_C\r
319typedef struct\r
320{\r
321 int b0;\r
322 int b1;\r
323 int b2;\r
324 int b3;\r
325 int b4;\r
326 int b5;\r
327 int b6;\r
328 int b7;\r
329} intblock;\r
330\r
331PICO_INTERNAL_ASM void memcpy16(unsigned short *dest, unsigned short *src, int count)\r
332{\r
333 if ((((int)dest | (int)src) & 3) == 0)\r
334 {\r
335 if (count >= 32) {\r
336 memcpy32((int *)dest, (int *)src, count/2);\r
337 count&=1;\r
338 } else {\r
339 for (; count >= 2; count -= 2, dest+=2, src+=2)\r
340 *(int *)dest = *(int *)src;\r
341 }\r
342 }\r
343 while (count--)\r
344 *dest++ = *src++;\r
345}\r
346\r
347\r
348PICO_INTERNAL_ASM void memcpy16bswap(unsigned short *dest, void *src, int count)\r
349{\r
350 unsigned char *src_ = src;\r
351\r
352 for (; count; count--, src_ += 2)\r
353 *dest++ = (src_[0] << 8) | src_[1];\r
354}\r
355\r
356\r
357PICO_INTERNAL_ASM void memcpy32(int *dest, int *src, int count)\r
358{\r
359 intblock *bd = (intblock *) dest, *bs = (intblock *) src;\r
360\r
361 for (; count >= sizeof(*bd)/4; count -= sizeof(*bd)/4)\r
362 *bd++ = *bs++;\r
363\r
364 dest = (int *)bd; src = (int *)bs;\r
365 while (count--)\r
366 *dest++ = *src++;\r
367}\r
368\r
369\r
370PICO_INTERNAL_ASM void memset32(int *dest, int c, int count)\r
371{\r
372 for (; count >= 8; count -= 8, dest += 8)\r
373 dest[0] = dest[1] = dest[2] = dest[3] =\r
374 dest[4] = dest[5] = dest[6] = dest[7] = c;\r
375\r
376 while (count--)\r
377 *dest++ = c;\r
378}\r
379#endif\r
380\r