dualcore integration in famc, bram cart C code, psp bugfixes
[picodrive.git] / Pico / Misc.c
CommitLineData
cc68a136 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
cea65903 88// vcounter values for PicoFrameSimple\r
cc68a136 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
cc68a136 134\r
1dceadae 135// (see Genesis Plus for Wii/GC code and docs for info,\r
136// full game list and better code).\r
cc68a136 137\r
138unsigned int lastSSRamWrite = 0xffff0000;\r
139\r
1dceadae 140// sram_reg: LAtd sela (L=pending SCL, A=pending SDA, t=(unused),\r
cc68a136 141// d=SRAM was detected (header or by access), s=started, e=save is EEPROM, l=old SCL, a=old SDA)\r
eff55556 142PICO_INTERNAL void SRAMWriteEEPROM(unsigned int d) // ???? ??la (l=SCL, a=SDA)\r
cc68a136 143{\r
1dceadae 144 unsigned int sreg = Pico.m.sram_reg, saddr = Pico.m.eeprom_addr, scyc = Pico.m.eeprom_cycle, ssa = Pico.m.eeprom_slave;\r
cc68a136 145\r
1dceadae 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
cc68a136 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
1dceadae 154 elprintf(EL_EEPROM, "eeprom: -start-");\r
cc68a136 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
1dceadae 160 elprintf(EL_EEPROM, "eeprom: -stop-");\r
cc68a136 161 sreg &= ~8;\r
162 }\r
163 }\r
1dceadae 164 else if((sreg & 8) && !(sreg & 2) && (d&2))\r
165 {\r
cc68a136 166 // we are started and SCL went high - next cycle\r
167 scyc++; // pre-increment\r
1dceadae 168 if(SRam.eeprom_type) {\r
cc68a136 169 // X24C02+\r
7969166e 170 if((ssa&1) && scyc == 18) {\r
171 scyc = 9;\r
172 saddr++; // next address in read mode\r
1dceadae 173 /*if(SRam.eeprom_type==2) saddr&=0xff; else*/ saddr&=0x1fff; // mask\r
7969166e 174 }\r
1dceadae 175 else if(SRam.eeprom_type == 2 && scyc == 27) scyc = 18;\r
7969166e 176 else if(scyc == 36) scyc = 27;\r
177 } else {\r
178 // X24C01\r
cc68a136 179 if(scyc == 18) {\r
180 scyc = 9; // wrap\r
181 if(saddr&1) { saddr+=2; saddr&=0xff; } // next addr in read mode\r
7969166e 182 }\r
183 }\r
1dceadae 184 elprintf(EL_EEPROM, "eeprom: scyc: %i", scyc);\r
cc68a136 185 }\r
1dceadae 186 else if((sreg & 8) && (sreg & 2) && !(d&2))\r
187 {\r
cc68a136 188 // we are started and SCL went low (falling edge)\r
1dceadae 189 if(SRam.eeprom_type) {\r
7969166e 190 // X24C02+\r
191 if(scyc == 9 || scyc == 18 || scyc == 27); // ACK cycles\r
1dceadae 192 else if( (SRam.eeprom_type == 3 && scyc > 27) || (SRam.eeprom_type == 2 && scyc > 18) ) {\r
cc68a136 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
1dceadae 199 elprintf(EL_EEPROM, "eeprom: write done, addr inc to: %x, last byte=%02x", saddr, *pm);\r
cc68a136 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
7969166e 206 saddr<<=1;\r
1dceadae 207 if(SRam.eeprom_type == 2) saddr&=0xff; else saddr&=0x1fff; // mask\r
7969166e 208 saddr|=d&1;\r
1dceadae 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
7969166e 213 }\r
cc68a136 214 } else {\r
7969166e 215 // slave address\r
216 ssa<<=1; ssa|=d&1;\r
1dceadae 217 if(scyc==8) elprintf(EL_EEPROM, "eeprom: slave done: %x", ssa);\r
cc68a136 218 }\r
7969166e 219 } else {\r
220 // X24C01\r
cc68a136 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
1dceadae 229 elprintf(EL_EEPROM, "eeprom: write done, addr inc to: %x, last byte=%02x", saddr>>1, *pm);\r
cc68a136 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
1dceadae 236 if(scyc==8) elprintf(EL_EEPROM, "eeprom: addr done: %x", saddr>>1);\r
cc68a136 237 }\r
7969166e 238 }\r
cc68a136 239 }\r
240\r
241 sreg &= ~3; sreg |= d&3; // remember SCL and SDA\r
1dceadae 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
cc68a136 246}\r
247\r
eff55556 248PICO_INTERNAL_ASM unsigned int SRAMReadEEPROM(void)\r
cc68a136 249{\r
1dceadae 250 unsigned int shift, d;\r
251 unsigned int sreg, saddr, scyc, ssa, interval;\r
cc68a136 252\r
253 // flush last pending write\r
254 SRAMWriteEEPROM(Pico.m.sram_reg>>6);\r
255\r
1dceadae 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
cc68a136 259\r
1dceadae 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
cc68a136 273 // started and first command word received\r
274 shift = 17-scyc;\r
1dceadae 275 if (SRam.eeprom_type) {\r
7969166e 276 // X24C02+\r
1dceadae 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
7969166e 280 d = (SRam.data[saddr]>>shift)&1;\r
281 }\r
282 } else {\r
283 // X24C01\r
1dceadae 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
7969166e 287 d = (SRam.data[saddr>>1]>>shift)&1;\r
288 }\r
289 }\r
cc68a136 290 }\r
cc68a136 291\r
1dceadae 292 return (d << SRam.eeprom_bit_out);\r
cc68a136 293}\r
294\r
eff55556 295PICO_INTERNAL void SRAMUpdPending(unsigned int a, unsigned int d)\r
cc68a136 296{\r
1dceadae 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
cc68a136 312 }\r
313\r
314 Pico.m.sram_reg = (unsigned char) sreg;\r
315}\r
cea65903 316\r
317\r
318#ifndef _ASM_MISC_C\r
70357ce5 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
eff55556 331PICO_INTERNAL_ASM void memcpy16(unsigned short *dest, unsigned short *src, int count)\r
cea65903 332{\r
80db4442 333 if ((((int)dest | (int)src) & 3) == 0)\r
70357ce5 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
cea65903 343 while (count--)\r
344 *dest++ = *src++;\r
345}\r
346\r
347\r
eff55556 348PICO_INTERNAL_ASM void memcpy16bswap(unsigned short *dest, void *src, int count)\r
0a051f55 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
eff55556 357PICO_INTERNAL_ASM void memcpy32(int *dest, int *src, int count)\r
cea65903 358{\r
70357ce5 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
cea65903 365 while (count--)\r
366 *dest++ = *src++;\r
367}\r
368\r
369\r
eff55556 370PICO_INTERNAL_ASM void memset32(int *dest, int c, int count)\r
cea65903 371{\r
70357ce5 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
cea65903 376 while (count--)\r
377 *dest++ = c;\r
378}\r
379#endif\r
380\r