5bb58145c0cd6d188e16621340cf92e9cc0c39bb
[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 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   //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
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 unsigned int SRAMReadEEPROM()\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 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 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 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 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 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