Björn Stenberg | 554b95a | 2002-03-27 09:25:09 +0000 | [diff] [blame] | 1 | #define _PAGE_ Jukebox notes |
| 2 | #include "head.t" |
| 3 | |
| 4 | <h2>Exception vectors</h2> |
| 5 | |
| 6 | <p>The first 0x200 bytes of the image appears to be the exception vector table. |
| 7 | The vectors are explained on pages 54 and 70-71 in the SH-1 Hardware Manual, |
| 8 | |
| 9 | <p>Here's the vector table for v5.03a: |
| 10 | |
| 11 | <table border=1><tr> |
| 12 | <th>Vector</th><th>Address</th><th>Description/interrupt source</th> |
| 13 | <tr><td> 0</td><td>09000200</td><td>Power-on reset PC</td></tr> |
| 14 | <tr><td> 1</td><td>0903f2bc</td><td>Power-on reset SP</td></tr> |
| 15 | <tr><td> 2</td><td>09000200</td><td>Manual reset PC</td></tr> |
| 16 | <tr><td> 3</td><td>0903f2bc</td><td>Manual reset SP</td></tr> |
| 17 | <tr><td> 11</td><td>09000cac</td><td>NMI</td></tr> |
| 18 | <tr><td> 64</td><td>0900c060</td><td>IRQ0</td></tr> |
| 19 | <tr><td> 70</td><td>09004934</td><td>IRQ6</td></tr> |
| 20 | <tr><td> 78</td><td>09004a38</td><td>DMAC3 DEI3</td></tr> |
| 21 | <tr><td> 80</td><td>0900dfd0</td><td>ITU0 IMIA0</td></tr> |
| 22 | <tr><td> 88</td><td>0900df60</td><td>ITU2 IMIA2</td></tr> |
| 23 | <tr><td> 90</td><td>0900df60</td><td>ITU2 OVI2</td></tr> |
| 24 | <tr><td>104</td><td>09004918</td><td>SCI1 ERI1</td></tr> |
| 25 | <tr><td>105</td><td>090049e0</td><td>SCI1 Rxl1</td></tr> |
| 26 | <tr><td>109</td><td>09010270</td><td>A/D ITI</td></tr> |
| 27 | </table> |
| 28 | |
| 29 | <p>From the use of address 0x0903f2bc as stack pointer, we can deduce |
| 30 | that the DRAM is located at address 0x09000000. |
| 31 | This is backed by the HW manual p102, which says that DRAM can only be at put on CS1, which is either 0x01000000 (8-bit) or 0x09000000 (16-bit). |
| 32 | |
| 33 | <p>The vector table also corresponds with the fact that there is code at address 0x200 of the image file. 0x200 is thus the starting point for all code. |
| 34 | |
| 35 | <h2>Port pins</h2> |
| 36 | <p><table><tr valign="top"><td> |
| 37 | |
| 38 | <p>Port A pin function configuration summary: |
| 39 | <table border=1> |
| 40 | <tr><th>Pin</th><th>Function</th><th>Input/output</th><th>Initial value</th><th>Used for</th></tr> |
| 41 | <tr><td>PA0</td><td>i/o</td><td>Input</td><td></td><td>DC adapter detect</td></tr> |
| 42 | <tr><td>PA1</td><td>/RAS</td><td>Output</td><td></td><td>DRAM</td></tr> |
| 43 | <tr><td>PA2</td><td>/CS6</td><td>Output</td><td></td><td>IDE</td></tr> |
| 44 | <tr><td>PA3</td><td>/WAIT</td></tr> |
| 45 | <tr><td>PA4</td><td>/WR</td><td>Output</td><td></td><td>DRAM+Flash</td></tr> |
| 46 | <tr><td>PA5</td><td>i/o</td><td>Input</td><td></td><td>Key: ON</td></tr> |
| 47 | <tr><td>PA6</td><td>/RD</td><td>Output</td><td></td><td>IDE</td></tr> |
| 48 | <tr><td>PA7</td><td>i/o</td><td>Output</td><td>0</td></tr> |
| 49 | <tr><td>PA8</td><td>i/o</td><td>Output</td><td>0</td></tr> |
| 50 | <tr><td>PA9</td><td>i/o</td><td>Output</td><td>1</td></tr> |
| 51 | <tr><td>PA10</td><td>i/o</td><td>Output</td></tr> |
| 52 | <tr><td>PA11</td><td>i/o</td><td>Input</td><td></td><td>Key: STOP</td></tr> |
| 53 | <tr><td>PA12</td><td>/IRQ0</td></tr> |
| 54 | <tr><td>PA13</td><td>i/o</td></tr> |
| 55 | <tr><td>PA14</td><td>i/o</td></tr> |
| 56 | <tr><td>PA15</td><td>i/o</td><td>Input</td><td></td><td>USB cable detect</td></tr> |
| 57 | </table> |
| 58 | |
| 59 | </td><td> |
| 60 | |
| 61 | <p>Port B pin function configuration summary: |
| 62 | <table border=1> |
| 63 | <tr><th>Pin</th><th>Function</th><th>Input/output</th><th>Initial value</th><th>Used for</th></tr> |
| 64 | <tr><td>PB0</td><td>i/o</td><td>Output</td><td></td><td>LCD</td></tr> |
| 65 | <tr><td>PB1</td><td>i/o</td><td>Output</td><td></td><td>LCD</td></tr> |
| 66 | <tr><td>PB2</td><td>i/o</td><td>Output</td><td></td><td>LCD</td></tr> |
| 67 | <tr><td>PB3</td><td>i/o</td><td>Output</td><td></td><td>LCD</td></tr> |
| 68 | <tr><td>PB4</td><td>i/o</td><td>Input</td></tr> |
| 69 | <tr><td>PB5</td><td>i/o</td><td>Output</td><td>1</td><td>I²C data</td></tr> |
| 70 | <tr><td>PB6</td><td>i/o</td><td>Output</td><td>0</td></tr> |
| 71 | <tr><td>PB7</td><td>i/o</td><td>Output</td><td></td><td>I²C clock</td></tr> |
| 72 | <tr><td>PB8</td><td>i/o</td></tr> |
| 73 | <tr><td>PB9</td><td>TxD0</td><td>Output</td><td></td><td>MPEG</td></tr> |
| 74 | <tr><td>PB10</td><td>RxD1</td><td>Input</td></td><td></td><td>Remote</td></tr> |
| 75 | <tr><td>PB11</td><td>TxD1</td><td>Output</td><td></td><td>Remote?</td></tr> |
| 76 | <tr><td>PB12</td><td>SCK0</td><td>Output</td><td></td><td>MPEG</td></tr> |
| 77 | <tr><td>PB13</td><td>i/o</td></tr> |
| 78 | <tr><td>PB14</td><td>/IRQ6</td><td>Input</td></tr> |
| 79 | <tr><td>PB15</td><td>i/o</td><td>Input</td></tr> |
| 80 | </table> |
| 81 | |
| 82 | |
| 83 | </td></tr></table> |
| 84 | |
| 85 | <p>Port C pin function configuration summary: |
| 86 | <table border=1> |
| 87 | <tr><th>Pin</th><th>Function</th><th>Input/output</th><th>Used for</th></tr> |
| 88 | <tr><td>PC0</td><td>i/o</td><td>Input</td><td>Key: - / PREV</td></tr> |
| 89 | <tr><td>PC1</td><td>i/o</td><td>Input</td><td>Key: MENU</td></tr> |
| 90 | <tr><td>PC2</td><td>i/o</td><td>Input</td><td>Key: + / NEXT</td></tr> |
| 91 | <tr><td>PC3</td><td>i/o</td><td>Input</td><td>Key: PLAY</td></tr> |
| 92 | <tr><td>PC4</td><td>i/o</td><td>Input</td></tr> |
| 93 | <tr><td>PC5</td><td>i/o</td><td>Input</td></tr> |
| 94 | <tr><td>PC6</td><td>i/o</td><td>Input</td></tr> |
| 95 | <tr><td>PC7</td><td>i/o</td><td>Input</td></tr> |
| 96 | </table> |
| 97 | |
| 98 | |
| 99 | <h2>Labels</h2> |
| 100 | <p>Note: Everything is about v5.03a. |
| 101 | |
| 102 | <ul> |
| 103 | <li>0x0200: Start point |
| 104 | <li>0x383d: Text: "Archos Jukebox hard drive is not bootable! Please insert a bootable floppy and press any key to try again" :-) |
| 105 | <li>0xc390: Address of "Update" string shown early on LCD. |
| 106 | <li>0xc8c0: Start of setup code |
| 107 | <li>0xc8c8: DRAM setup |
| 108 | <li>0xc4a0: Serial port 1 setup |
| 109 | <li>0xc40a: Port configuration setup |
| 110 | <li>0xe3bc: Character set conversion table |
| 111 | <li>0xfcd0: ITU setup |
| 112 | <li>0xc52a: Memory area #6 setup |
| 113 | <li>0x114b0: Start of menu strings |
| 114 | </ul> |
| 115 | |
| 116 | |
| 117 | <h2>Setup</h2> |
| 118 | |
| 119 | <p>The startup code at 0x200 (0x09000200) naturally begins with setting up the system. |
| 120 | |
| 121 | <h3>Vector Base Register</h3> |
| 122 | |
| 123 | <p>The first thing the code does is setting the VBR, Vector Base Register, |
| 124 | and thus move the exception vector table from the internal ROM at address 0 |
| 125 | to the DRAM at address 0x09000000: |
| 126 | |
| 127 | <pre> |
| 128 | 0x00000200: mov.l @(0x02C,pc),r1 ; 0x0000022C (0x09000000) |
| 129 | 0x00000202: ldc r1,vbr |
| 130 | </pre> |
| 131 | |
| 132 | <h3>Stack</h3> |
| 133 | |
| 134 | <p>The next instruction loads r15 with the contents of 0x228, which is 0x0903f2bc. This is the stack pointer, which is used all over the code. |
| 135 | |
| 136 | <pre> |
| 137 | 0x00000204: mov.l @(0x024,pc),r15 ; 0x00000228 (0x0903F2BC) |
| 138 | </pre> |
| 139 | |
| 140 | <p>After that the code jumps to the hardware setup at 0xc8c0. |
| 141 | <pre> |
| 142 | 0x00000206: mov.l @(0x01C,pc),r0 ; 0x00000220 (0x0900C8C0) |
| 143 | 0x00000208: jsr @r0 |
| 144 | </pre> |
| 145 | |
| 146 | <h3>DRAM controller</h3> |
| 147 | |
| 148 | <p>First up is DRAM setup, at 0xc8c8. It sets the memory controller registers: |
| 149 | |
| 150 | <pre> |
| 151 | 0x0000C8C8: mov.l @(0x068,pc),r2 ; 0x0000C930 (0x05FFFFA8) |
| 152 | 0x0000C8CA: mov.w @(0x05A,pc),r1 ; 0x0000C924 (0x1E00) |
| 153 | 0x0000C8CC: mov.l @(0x068,pc),r7 ; 0x0000C934 (0x0F0001C0) |
| 154 | 0x0000C8CE: mov.w r1,@r2 ; 0x1e00 -> DCR |
| 155 | 0x0000C8D0: mov.l @(0x068,pc),r2 ; 0x0000C938 (0x05FFFFAC) |
| 156 | 0x0000C8D2: mov.w @(0x054,pc),r1 ; 0x0000C926 (0x5AB0) |
| 157 | 0x0000C8D4: mov.w r1,@r2 ; 0x5ab0 -> RCR |
| 158 | 0x0000C8D6: mov.l @(0x068,pc),r2 ; 0x0000C93C (0x05FFFFB2) |
| 159 | 0x0000C8D8: mov.w @(0x050,pc),r1 ; 0x0000C928 (0x9605) |
| 160 | 0x0000C8DA: mov.w r1,@r2 ; 0x9505 -> RTCOR |
| 161 | 0x0000C8DC: mov.l @(0x064,pc),r2 ; 0x0000C940 (0x05FFFFAE) |
| 162 | 0x0000C8DE: mov.w @(0x04C,pc),r1 ; 0x0000C92A (0xA518) |
| 163 | 0x0000C8E0: mov.w r1,@r2 ; 0xa518 -> RTCSR |
| 164 | </pre> |
| 165 | |
| 166 | <h3>Serial port 0</h3> |
| 167 | |
| 168 | <p>Code starting at 0x483c. |
| 169 | |
| 170 | <p>As C code: |
| 171 | |
| 172 | <table border><tr><td bgcolor="#a0d6e8"> |
| 173 | <pre> |
| 174 | void setup_sci0(void) |
| 175 | { |
| 176 | /* set PB12 to output */ |
| 177 | PBIOR |= 0x1000; |
| 178 | |
| 179 | /* Disable serial port */ |
| 180 | SCR0 = 0x00; |
| 181 | |
| 182 | /* Syncronous, 8N1, no prescale */ |
| 183 | SMR0 = 0x80; |
| 184 | |
| 185 | /* Set baudrate 1Mbit/s */ |
| 186 | BRR0 = 0x03; |
| 187 | |
| 188 | /* use SCK as serial clock output */ |
| 189 | SCR0 = 0x01; |
| 190 | |
| 191 | /* Clear FER and PER */ |
| 192 | SSR0 &= 0xe7; |
| 193 | |
| 194 | /* Set interrupt D priority to 0 */ |
| 195 | IPRD &= 0x0ff0; |
| 196 | |
| 197 | /* set IRQ6 and IRQ7 to edge detect */ |
| 198 | ICR |= 0x03; |
| 199 | |
| 200 | /* set PB15 and PB14 to inputs */ |
| 201 | PBIOR &= 0x7fff; |
| 202 | PBIOR &= 0xbfff; |
| 203 | |
| 204 | /* set IRQ6 prio 8 and IRQ7 prio 0 */ |
| 205 | IPRB = ( IPRB & 0xff00 ) | 0x80; |
| 206 | |
| 207 | /* Enable Tx (only!) */ |
| 208 | SCR0 = 0x20; |
| 209 | } |
| 210 | </pre> |
| 211 | </td></tr></table> |
| 212 | |
| 213 | |
| 214 | <h3>Serial port 1</h3> |
| 215 | |
| 216 | <p>Code starting at 0x47a0. |
| 217 | |
| 218 | <p>As C code: |
| 219 | |
| 220 | <table border><tr><td bgcolor="#a0d6e8"> |
| 221 | <pre> |
| 222 | #define SYSCLOCK 12000000 |
| 223 | #define PRIORITY 8 |
| 224 | |
| 225 | void setup_sci1(int baudrate) |
| 226 | { |
| 227 | /* Disable serial port */ |
| 228 | SCR1 = 0; |
| 229 | |
| 230 | /* Set PB11 to Tx and PB10 to Rx */ |
| 231 | PBCR1 = (PBCR1 & 0xff0f) | 0xa0; |
| 232 | |
| 233 | /* Asynchronous, 8N1, no prescaler */ |
| 234 | SMR1 = 0; |
| 235 | |
| 236 | /* Set baudrate */ |
| 237 | BRR1 = SYSCLOCK / (baudrate * 32) - 1; |
| 238 | |
| 239 | /* Clear FER and PER */ |
| 240 | SSR1 &= 0xe7; |
| 241 | |
| 242 | /* Set interrupt priority to 8 */ |
| 243 | IPRE = (IPRE & 0x0fff) | (PRIORITY << 12); |
| 244 | |
| 245 | /* Enable Rx, Tx and Rx interrupt */ |
| 246 | SCR1 = 0x70; |
| 247 | } |
| 248 | </pre> |
| 249 | </td></tr></table> |
| 250 | |
| 251 | <h3>Pin configuration</h3> |
| 252 | |
| 253 | <p>Starting at 0xc40a: |
| 254 | |
| 255 | <p><tt>CASCR = 0xafff</tt>: Column Address Strobe Pin Control Register. Set bits CASH MD1 and CASL MD1. |
| 256 | |
| 257 | <h4>Port A</h4> |
| 258 | <br><tt>PACR1 = 0x0102</tt>: Set pin functions |
| 259 | <br><tt>PACR2 = 0xbb98</tt>: Set pin functions |
| 260 | <br><tt>PAIOR &= 0xfffe</tt>: PA0 is input |
| 261 | <br><tt>PAIOR &= 0xffdf</tt>: PA5 is input |
| 262 | <br><tt>PADR &= 0xff7f</tt>: Set pin PA7 low |
| 263 | <br><tt>PAIOR |= 0x80</tt>: PA7 is output |
| 264 | <br><tt>PAIOR |= 0x100</tt>: PA8 is output |
| 265 | <br><tt>PADR |= 0x200</tt>: Set pin PA9 high |
| 266 | <br><tt>PAIOR |= 0x200</tt>: PA9 is output |
| 267 | <br><tt>PAIOR |= 0x400</tt>: PA10 is output |
| 268 | <br><tt>PAIOR &= 0xf7ff</tt>: PA11 is input |
| 269 | <br><tt>PAIOR &= 0xbfff</tt>: PA14 is input |
| 270 | <br><tt>PAIOR = 0x7fff</tt>: PA15 is input |
| 271 | <br><tt>PADR &= 0xfeff</tt>: Set pin PA8 low |
| 272 | |
| 273 | <h4>Port B</h4> |
| 274 | <br><tt>PBCR1 = 0x12a8</tt>: Set pin functions |
| 275 | <br><tt>PBCR2 = 0x0000</tt>: Set pin functions |
| 276 | <br><tt>PBDR &= 0xffef</tt>: Set pin PB4 low |
| 277 | <br><tt>PBIOR &= 0xffef</tt>: PB4 is input |
| 278 | <br><tt>PBIOR |= 0x20</tt>: PB5 is output |
| 279 | <br><tt>PBIOR |= 0x40</tt>: PA6 is output |
| 280 | <br><tt>PBDR &= 0xffbf</tt>: Set pin PB6 low |
| 281 | <br><tt>PBDR |= 0x20</tt>: Set pin PB5 high |
| 282 | |
| 283 | <h3>ITU (Integrated Timer Pulse Unit)</h3> |
| 284 | |
| 285 | <p>Starting at 0xfcd0: |
| 286 | |
| 287 | <p><tt>TSNC &= 0xfe</tt>: The timer counter for channel 0 (TCNT0) operates independently of other channels |
| 288 | <br><tt>TMDR &= 0xfe</tt>: Channel 0 operates in normal (not PWM) mode |
| 289 | <br><tt>GRA0 = 0x1d4c</tt>: |
| 290 | <br><tt>TCR0 &= 0x67; TCR0 |= 0x23</tt>: TCNT is cleared by general register A (GRA) compare match or input capture. Counter clock = f/8 |
| 291 | <br><tt>TIOR0 = 0x88</tt>: Compare disabled |
| 292 | <br><tt>TIER0 = 0xf9</tt>: Enable interrupt requests by IMFA (IMIA) |
| 293 | <br><tt>IPRC &= 0xff0f; IPRC |= 0x30</tt>: Set ITU0 interrupt priority level 3. |
| 294 | <br><tt>TSTR |= 0x01</tt>: Start TCNT0 |
| 295 | |
| 296 | <h3>Memory area #6 ?</h3> |
| 297 | |
| 298 | <p>From 0xc52a: |
| 299 | |
| 300 | <p><tt>PADR |= 0x0200</tt>: Set PA13 high |
| 301 | <br><tt>WCR1 = 0x40ff</tt>: Enable /WAIT support for memory area 6. Hmmm, what's on CS6? |
| 302 | <br><tt>WCR1 &= 0xfdfd</tt>: Turn off RW5 (was off already) and WW1 (enable short address output cycle). |
| 303 | <br><tt>WCR3 &= 0xe7ff</tt>: Turn off A6LW1 and A6LW0; 1 wait state for CS6. |
| 304 | <br><tt>ICR |= 0x80</tt>: Interrupt is requested on falling edge of IRQ0 input |
| 305 | |
| 306 | <h2>Remote control</h2> |
| 307 | <p>Tjerk Schuringa reports: |
| 308 | "Finally got that extra bit going on my bitpattern generator. So far I fed only |
| 309 | simple characters to my jukebox, and this is the result: |
| 310 | |
| 311 | <pre> |
| 312 | START D0 1 2 3 4 5 6 7 STOP FUNCTION |
| 313 | 0 0 0 0 0 0 1 1 1 1 VOL- (the one I got already) |
| 314 | 0 0 0 0 1 0 1 1 VOL+ (figures) |
| 315 | 0 0 0 1 0 0 1 1 + |
| 316 | 0 0 1 0 0 0 1 1 - |
| 317 | 0 1 0 0 0 0 1 1 STOP |
| 318 | 1 0 0 0 0 0 1 1 PLAY |
| 319 | </pre> |
| 320 | |
| 321 | <p>I also found that "repeat" functions (keep a button depressed) needs to be |
| 322 | faster than 0.5 s. If it is around 1 second or more it is interpreted as a |
| 323 | seperate keypress. So far I did not get the "fast forward" function because the |
| 324 | fastest I can get is 0.5 s. |
| 325 | |
| 326 | <p>Very important: the baudrate is indeed 9600 baud! These pulses are fed to the |
| 327 | second ring on the headphone jack, and (if I understood correctly) go to RxD1 |
| 328 | of the SH1." |
| 329 | |
| 330 | <h2>LCD display</h2> |
| 331 | |
| 332 | <p>The Recorder uses a Shing Yih Technology G112064-30 graphic LCD display with 112x64 pixels. The controller is a Solomon SSD1815Z. |
| 333 | |
| 334 | <p>It's not yet known what display/controller the Jukebox has, but I'd be surprised if it doesn't use a similar controller. |
| 335 | |
| 336 | <p>Starting at 0xE050, the code flicks PB2 and PB3 a great deal and then some with PB1 and PB0. Which gives us the following connections: |
| 337 | |
| 338 | <table border><tr><th>CPU pin</th><th>LCD pin</th></tr> |
| 339 | <tr><td>PB0</td><td>DC</td></tr> |
| 340 | <tr><td>PB1</td><td>CS1</td></tr> |
| 341 | <tr><td>PB2</td><td>SCK</td></tr> |
| 342 | <tr><td>PB3</td><td>SDA</td></tr> |
| 343 | </table> |
| 344 | |
| 345 | <p>The Recorder apparently has the connections this way (according to Gary Czvitkovicz): |
| 346 | <table border><tr><th>CPU pin</th><th>LCD pin</th></tr> |
| 347 | <tr><td>PB0</td><td>SDA</td></tr> |
| 348 | <tr><td>PB1</td><td>SCK</td></tr> |
| 349 | <tr><td>PB2</td><td>DC</td></tr> |
| 350 | <tr><td>PB3</td><td>CS1</td></tr> |
| 351 | </table> |
| 352 | |
Björn Stenberg | 7e8e100 | 2002-04-11 13:58:49 +0000 | [diff] [blame^] | 353 | <a name="charsets"><p>The player charsets: |
Björn Stenberg | 554b95a | 2002-03-27 09:25:09 +0000 | [diff] [blame] | 354 | |
| 355 | <p><table border=0><tr> |
| 356 | <td><img src="codes_old.png" width=272 height=272><br> |
| 357 | <small>Old LCD charset (before v4.50)</small></td> |
| 358 | <td><img src="codes_new.png" width=272 height=272><br> |
| 359 | <small>New LCD charset (after v4.50)</small></td></tr></table> |
| 360 | |
Björn Stenberg | 7e8e100 | 2002-04-11 13:58:49 +0000 | [diff] [blame^] | 361 | <p>And the Recorder charset looks like this: |
| 362 | <br> |
| 363 | <img src="codes_rec.png"> |
Björn Stenberg | 554b95a | 2002-03-27 09:25:09 +0000 | [diff] [blame] | 364 | |
| 365 | <h3>Code</h3> |
| 366 | |
| 367 | <p>This C snippet write a byte to the Jukebox LCD controller. |
| 368 | The 'data' flag inticates if the byte is a command byte or a data byte. |
| 369 | |
| 370 | <table border><tr><td bgcolor="#a0d6e8"> |
| 371 | <pre> |
| 372 | #define DC 1 |
| 373 | #define CS1 2 |
| 374 | #define SDA 4 |
| 375 | #define SCK 8 |
| 376 | |
| 377 | void lcd_write(int byte, int data) |
| 378 | { |
| 379 | int i; |
| 380 | char on,off; |
| 381 | |
| 382 | PBDR &= ~CS1; /* enable lcd chip select */ |
| 383 | |
| 384 | if ( data ) { |
| 385 | on=~(SDA|SCK); |
| 386 | off=SCK|DC; |
| 387 | } |
| 388 | else { |
| 389 | on=~(SDA|SCK|DC); |
| 390 | off=SCK; |
| 391 | } |
| 392 | /* clock out each bit, MSB first */ |
| 393 | for (i=0x80;i;i>>=1) |
| 394 | { |
| 395 | PBDR &= on; |
| 396 | if (i & byte) |
| 397 | PBDR |= SDA; |
| 398 | PBDR |= off; |
| 399 | } |
| 400 | |
| 401 | PBDR |= CS1; /* disable lcd chip select */ |
| 402 | } |
| 403 | </pre> |
| 404 | </td></tr></table> |
| 405 | |
| 406 | <h2>Firmware size</h2> |
| 407 | |
| 408 | <p>Joachim Schiffer found out that firmware files have to be at least 51200 |
| 409 | bytes to be loaded by newer firmware ROMs. |
| 410 | So my "first program" only works on players with older firmware in ROM |
| 411 | (my has 3.18). Joachim posted a |
| 412 | <a href="mail/jukebox-archive-2001-12/att-0087/01-AJBREC.ajz">padded version</a> that works everywhere. |
| 413 | |
Björn Stenberg | 7e8e100 | 2002-04-11 13:58:49 +0000 | [diff] [blame^] | 414 | <p>Tests have shown that firmware sizes above 200K won't load. |
| 415 | |
Björn Stenberg | 554b95a | 2002-03-27 09:25:09 +0000 | [diff] [blame] | 416 | #include "foot.t" |