sram handling refactored
[picodrive.git] / Pico / Misc.c
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
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
48 };\r
49 \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
86 };\r
87 \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
127 311,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 // NFL Quarterback Club*, Frank Thomas Big Hurt Baseball (X24C04?)\r
135 // College Slam, Blockbuster World Video Game Championship II, NBA Jam (X24C04?)\r
136 // HardBall '95\r
137 \r
138 // the above sports games use addr 0x200000 for SCL line (handled in Memory.c)\r
139 \r
140 unsigned int lastSSRamWrite = 0xffff0000;\r
141 \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 PICO_INTERNAL void SRAMWriteEEPROM(unsigned int d) // ???? ??la (l=SCL, a=SDA)\r
145 {\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
147 \r
148   //printf("EEPROM write %i\n", d&3);\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
150   saddr&=0x1fff;\r
151 \r
152   if(sreg & d & 2) {\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
160         sreg |= 0x8000;\r
161       }\r
162       //saddr = 0;\r
163       scyc = 0;\r
164       sreg |= 8;\r
165     } else if(!(sreg & 1) && (d&1)) {\r
166       // SDA went high == stop command\r
167       //dprintf("-stop-");\r
168       sreg &= ~8;\r
169     }\r
170   }\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
174     if(sreg & 0x20) {\r
175       // X24C02+\r
176       if((ssa&1) && scyc == 18) {\r
177         scyc = 9;\r
178         saddr++; // next address in read mode\r
179         if(sreg&0x4000) saddr&=0xff; else saddr&=0x1fff; // mask\r
180       }\r
181       else if((sreg&0x4000) && scyc == 27) scyc = 18;\r
182       else if(scyc == 36) scyc = 27;\r
183     } else {\r
184       // X24C01\r
185       if(scyc == 18) {\r
186         scyc = 9;  // wrap\r
187         if(saddr&1) { saddr+=2; saddr&=0xff; } // next addr in read mode\r
188       }\r
189     }\r
190     //dprintf("scyc: %i", scyc);\r
191   }\r
192   else if((sreg & 8) && (sreg & 2) && !(d&2)) {\r
193     // we are started and SCL went low (falling edge)\r
194     if(sreg & 0x20) {\r
195       // X24C02+\r
196       if(scyc == 9 || scyc == 18 || scyc == 27); // ACK cycles\r
197       else if( (!(sreg&0x4000) && scyc > 27) || ((sreg&0x4000) && scyc > 18) ) {\r
198         if(!(ssa&1)) {\r
199           // data write\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
205           }\r
206           SRam.changed = 1;\r
207         }\r
208       } else if(scyc > 9) {\r
209         if(!(ssa&1)) {\r
210           // we latch another addr bit\r
211           saddr<<=1;\r
212           if(sreg&0x4000) saddr&=0xff; else saddr&=0x1fff; // mask\r
213           saddr|=d&1;\r
214           //if(scyc==17||scyc==26) dprintf("addr reg done: %x", saddr);\r
215         }\r
216       } else {\r
217         // slave address\r
218         ssa<<=1; ssa|=d&1;\r
219         //if(scyc==8) dprintf("slave done: %x", ssa);\r
220       }\r
221     } else {\r
222       // X24C01\r
223       if(scyc == 9); // ACK cycle, do nothing\r
224       else if(scyc > 9) {\r
225         if(!(saddr&1)) {\r
226           // data write\r
227           unsigned char *pm=SRam.data+(saddr>>1);\r
228           *pm <<= 1; *pm |= d&1;\r
229           if(scyc == 17) {\r
230             saddr=(saddr&0xf9)|((saddr+2)&6); // only 2 lowest bits are incremented\r
231             //dprintf("addr inc: %x", saddr>>1);\r
232           }\r
233           SRam.changed = 1;\r
234         }\r
235       } else {\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
239       }\r
240     }\r
241   }\r
242 \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
248 }\r
249 \r
250 PICO_INTERNAL_ASM unsigned int SRAMReadEEPROM(void)\r
251 {\r
252   unsigned int shift, d=0;\r
253   unsigned int sreg, saddr, scyc, ssa;\r
254 \r
255   // flush last pending write\r
256   SRAMWriteEEPROM(Pico.m.sram_reg>>6);\r
257 \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
260 \r
261   if(SekCyclesDoneT()-lastSSRamWrite < 46) {\r
262     // data was just written, there was no time to respond (used by sports games)\r
263     d = (sreg>>6)&1;\r
264   } else if((sreg & 8) && scyc > 9 && scyc != 18 && scyc != 27) {\r
265     // started and first command word received\r
266     shift = 17-scyc;\r
267     if(sreg & 0x20) {\r
268       // X24C02+\r
269       if(ssa&1) {\r
270         //dprintf("read: addr %02x, cycle %i, reg %02x", saddr, scyc, sreg);\r
271         d = (SRam.data[saddr]>>shift)&1;\r
272       }\r
273     } else {\r
274       // X24C01\r
275       if(saddr&1) {\r
276         d = (SRam.data[saddr>>1]>>shift)&1;\r
277       }\r
278     }\r
279   }\r
280   //else dprintf("r ack");\r
281 \r
282   return d;\r
283 }\r
284 \r
285 PICO_INTERNAL void SRAMUpdPending(unsigned int a, unsigned int d)\r
286 {\r
287   unsigned int sreg = Pico.m.sram_reg;\r
288 \r
289   if(!(a&1)) sreg|=0x20;\r
290 \r
291   if(sreg&0x20) { // address through 0x200000\r
292     if(!(a&1)) {\r
293       sreg&=~0x80;\r
294       sreg|=d<<7;\r
295     } else {\r
296       sreg&=~0x40;\r
297       sreg|=(d<<6)&0x40;\r
298     }\r
299   } else {\r
300     sreg&=~0xc0;\r
301     sreg|=d<<6;\r
302   }\r
303 \r
304   Pico.m.sram_reg = (unsigned char) sreg;\r
305 }\r
306 \r
307 \r
308 #ifndef _ASM_MISC_C\r
309 PICO_INTERNAL_ASM void memcpy16(unsigned short *dest, unsigned short *src, int count)\r
310 {\r
311         while (count--)\r
312                 *dest++ = *src++;\r
313 }\r
314 \r
315 \r
316 PICO_INTERNAL_ASM void memcpy16bswap(unsigned short *dest, void *src, int count)\r
317 {\r
318         unsigned char *src_ = src;\r
319 \r
320         for (; count; count--, src_ += 2)\r
321                 *dest++ = (src_[0] << 8) | src_[1];\r
322 }\r
323 \r
324 \r
325 PICO_INTERNAL_ASM void memcpy32(int *dest, int *src, int count)\r
326 {\r
327         while (count--)\r
328                 *dest++ = *src++;\r
329 }\r
330 \r
331 \r
332 PICO_INTERNAL_ASM void memset32(int *dest, int c, int count)\r
333 {\r
334         while (count--)\r
335                 *dest++ = c;\r
336 }\r
337 #endif\r
338 \r