gp32mon.ASM Assembled with CASM08Z 2/5/03 8:34:07 PM PAGE 1 1 * Motorola's GP32 Monitor ROM 2 * Labels and Comments by Jed Margolin February 2003 3 * 0000 4 #pagelength 48t 0000 5 #pagewidth 132t 0000 6 $base 10t 7 8 * The Motorola Monitor code was read using the PE Micro Debugger. Because the 9 * Debugger provides no method of saving the code, I did a screen capture, 10 * pasted it into Microsoft Word, printed it into Paperport, and used the 11 * Paperport OCR (Omni Lite) to convert it into text. (Omni Lite did a much 12 * better job than Textbridge Pro 98.) The font used by PE Micro does not 13 * lend itself to OCR. 14 * 15 * All labels and comments are mine. 16 * 17 *======================================================== 0000 18 $INCLUDE 'gp32.h' ; Equates for GP32 0000 19 $INCLUDE 'motpod.h' ; Equates for GP32 20 *======================================================== 21 *======================================================== 22 * These are the entry points from the routine that checks the Security Code. 23 * 24 * This is how Security seems to work: 25 * 26 * Power-On Reset -> User Mode: All memory is accessible. 27 * 28 * Power-On Reset -> Monitor Mode: 29 * 1. All memory is accessible so the Internal Monitor Code can 30 * check the Security Bytes 31 * 2. If the Security Code matches, it takes the last data it received 32 * (which would be from $FFFD) and writes it to $FFFF. All memory 33 * remains accessible. 34 * 3. If the Security Code does not match, it reads $FFFF, and Security 35 * Mode makes Flash Memory inaccessible. 36 * 37 * The data written to $FFFF after a successful Security Code match may 38 * be irrelevant and it is only whether the first access to $FFFF is a 39 * write or a read that matters. 40 * gp32mon.ASM Assembled with CASM08Z 2/5/03 8:34:07 PM PAGE 2 41 * The Security Mode remains as selected until another Power-On Reset, 42 * so that a Security Code failure requires another Power-On Reset. 43 * 44 * Since my monitor runs from User Mode, Security Mode is inactive, so that 45 * the code cannot be secured. 46 * 47 * Unfortunately, the PE Micro Debugger checks several Security Code bytes 48 * at startup. It also checks to see if the Power-On-Reset (POR) Flag is set. 49 * Here is the sequence obtained from capturing the Serial Port data: 50 * 4A FE FB Read $FEFB = $04 (revision number?) 51 * 4A FF F6 Read $FFF6 = data (TIM1 Channel 0 high byte: a Security Byte) 52 * 4A FF F7 Read $FFF7 = data (TIM1 Channel 0 low byte: a Security Byte) 53 * 4A FE FB Read $FEFB = $04 (again) 54 * 4A FE 01 Read $FE01 = data (Reset Status Register; clears the I flags) 55 * 0C Read Stack Pointer 56 * 49 00 FE 10 Write $10 to $00FE (high byte of Return Address on Stack) 57 * 19 00 IWriteto $00FF (low byte of Return Address on Stack) 58 * 28 Run (RTI) 59 * 60 * This sends the program to $1000, which is an illegal address, causing an 61 * MCU Reset. It starts over, going back through Security Code verification, 62 * and ends up back through this sequence. However, this time the POR Flag is 63 * not set. The PE Micro software seems to want to make sure it is talking to a 64 * Motorola part. There are other parts in the data stream where PE Micro 65 * Software deliberately causes an Illegal Instruction to be executed, thereby 66 * causing an Illegal Instruction Reset. 67 * 68 * At some point the PE Micro software might read location $0040 (sflag) which 69 * contains information about Security. 70 * sflag(7) = 1: We used parallel data input for the Security bytes 71 * sflag(6) = 1: Passed Security Code, 0: Failed 72 * FE20 73 ORG $FE20 74 75 * We passed security. FE20 [02] F7 76 ENTRY1: STA ,X 77 78 * Intruder Alert. FE21 [02] F6 79 ENTRY2: LDA ,X FE22 [05] 000002 80 BRSET 0,PORTA,br1 ; not a BREAK gp32mon.ASM Assembled with CASM08Z 2/5/03 8:34:07 PM PAGE 3 FE25 [02] BC41 81 JMP $0041 ; BREAK, so crash and burn 82 83 * The Monitor is supposed to run after failing the security check, but reading 84 * a Flash location should return invalid data and trying to execute code from 85 * Flash should make it crash. 86 87 * If we say the part is blank, it will skip GETCHAR, and get to 88 * the end very fast, whether or not the part is blank. 89 90 * If we say the part isn't blank, it will check the security bytes. If it gets 91 * one that doesn't match, it will continue to call GETCHAR FE27 [09] 83 92 br1: SWI ; Interrupt to SWIVEC 93 *------------------------------------------------------- 94 * Software Interrupts are produced either by the SWI instruction or 95 * by the Breakpoint Register. The Stack contains the information for 96 * returning to the User's program, or for starting it if the Stack is set up 97 * by the Host PC. FE28 [04] 1104 98 SWIVEC: BCLR 0,DDRA ; Serial In FE2A [02] 8B 99 PSHH ; save HReg 100 101 * Send a Break Character to say we are ready FE2B [04] 1100 102 BCLR 0,PORTA ; used to make Serial Out=0 FE2D [04] AD52 103 BSR SENDBREAK ; ends with BRA GETCMD, ACC contains low byte 104 ; of start vector = $00; PA0 as in input 105 106 * This is the COMMAND Interpreter FE2F [04] AD66 107 GETCMD: BSR GETCHAR FE31 [02] 87 108 PSHA ; save it 109 110 * READ Address $4A, Write Address $49, IRead $1A, IWrite $19, 111 * ReadSP $0C, Run $28 112 FE32 [01] 48 113 ASLA 114 * READ Address $94, Write Address $92, IRead $34, IWrite $32, 115 * ReadSP $18, Run $50 FE33 [03] 2A07 116 BPL br4 ; not Read Address or Write Address 117 118 ; We have a Read Address or Write Address command, get the address FE35 [04] AD60 119 BSR GETCHAR FE37 [02] 87 120 PSHA gp32mon.ASM Assembled with CASM08Z 2/5/03 8:34:07 PM PAGE 4 FE38 [02] 8A 121 PULH FE39 [04] AD5C 122 BSR GETCHAR FE3B [01] 97 123 TAX 124 125 * The address to be accessed is in XREGs 126 * 127 * READ Address $4A: 0 1 0 0 1 0 1 0 128 * Write Address $49: 0 1 0 0 1 0 0 1 129 * IRead $1A: 0 0 0 1 1 0 1 0 130 * IWrite $19: 0 0 0 1 1 0 0 1 131 * ReadSP $0C: 0 0 0 0 1 1 0 0 132 * Run $28: 0 0 1 0 1 0 0 0 133 * 134 * CCR V x x H I N Z C 135 * 136 137 * We have Read Address, Write Address, IRead, IWrite, ReadSP, or Run FE3C [02] 86 138 br4: PULA ; get the original command FE3D [02] 84 139 TAP ; Transfer ACC to CCR FE3E [03] 251C 140 BCS br5 ; Write Address or IWrite 141 142 * this leaves Read Address, IRead, ReadSP, or Run FE40 [04] AD33 143 BSR CheckBreak ; Look for BREAK character from Host PC FE42 [02] 84 144 TAP ; Transfer ACC to CCR FE43 [03] 280B 145 BHCC br7 ; branch on H Flag clear leaves: Read Address, ReadSp, 146 ; or Run 147 * We have IRead FE45 [03] E601 148 LDA 1,X ; looks like we are sending something back FE47 [04] AD61 149 BSR SENDCHAR FE49 [02] AF02 150 AIX #2 151 * Read Address FE4B [02] F6 152 br10: LDA ,X FE4C [04] AD5C 153 br15: BSR SENDCHAR FE4E [03] 20DF 154 BRA GETCMD 155 156 * We are left to consider: Read Address, ReadSp, or Run FE50 [03] 27F9 157 br7: BEQ br10 ; Read Address FE52 [03] 2B19 158 BMI ReadSP ; ReadSP FE54 [02] A828 159 EOR #$28 ; Run User Program FE56 [03] 2702 160 BEQ br12 ; we have a match gp32mon.ASM Assembled with CASM08Z 2/5/03 8:34:07 PM PAGE 5 FE58 [04] AD27 161 BSR SENDBREAK 162 * Unknown command. SENDBREAK ends with BRA GETCMD, ACC contains low byte of 163 * start vector = $00; PA0 as in input 164 165 * Run User program FE5A [02] 8A 166 br12: PULH ; restore HReg FE5B [07] 80 167 RTI 168 *--------------------- 169 * We are doing a Write Command FE5C [03] 2907 170 br5: BHCS br13 ; branch if H Flag is set, which only happens in IRead 171 ; and IWrite FE5E [04] AD37 172 BSR GETCHAR ; get the data to write FE60 [04] AD13 173 BSR CheckBreak ; Look for BREAK character from Host PC FE62 [02] F7 174 br14: STA ,X ; it looks like we did a Write Address FE63 [03] 20CA 175 BRA GETCMD ; get the next command 176 FE65 [04] AD30 177 br13: BSR GETCHAR ; get the data to write FE67 [04] AD0C 178 BSR CheckBreak ; Look for BREAK character from Host PC? FE69 [02] AF01 179 AIX #1 ; it looks like we are doing an IWrite FE6B [03] 20F5 180 BRA br14 181 *--------------------- FE6D [02] 95 182 ReadSP: TSX FE6E [02] 8B 183 PSHH FE6F [02] 86 184 PULA FE70 [04] AD38 185 BSR SENDCHAR FE72 [01] 9F 186 TXA FE73 [03] 20D7 187 BRA br15 188 *------------------------- 189 * Give the Host a chance to send a BREAK character 190 CheckBreak: FE75 [02] 87 191 PSHA FE76 [02] A60B 192 LDA #$0B FE78 [04] AD54 193 br18: BSR GetBit ; This gets a serial bit and returns it in Carry Flag; 194 ; it does not change DDRA FE7A [03] 2404 195 BCC br17 FE7C [03] 4BFA 196 DBNZA br18 FE7E [02] 86 197 PULA FE7F [04] 81 198 RTS FE80 [02] 86 199 br17: PULA 200 *-------------------------- gp32mon.ASM Assembled with CASM08Z 2/5/03 8:34:07 PM PAGE 6 201 * Send a Break Character; 202 * Goes to GETCMD with low byte of START address ($00) and with PA0 as in input 203 * wait for Serial In to go high, wait, 204 * set Serial to Out, wait, 205 * set Serial to In, 206 * increment SP by 2, 207 * load ACC with contents of $FFFF 208 * goto GETCMD 209 210 SENDBREAK: FE81 [05] 0100FD 211 BRCLR 0,PORTA,SENDBREAK ; wait for Serial In to go high 212 FE84 [02] AEA9 213 LDX #$0A9 ; wait 2+$A9*3 = 2+169*3 = 509 cycles = FE86 [03] 5BFE 214 br18a: DBNZX br18a ; 509/2.4576 = 207us, 2 bits at 9600 (1/9600=104.166us) 215 216 * Low for 10 bits (1 start bit, 8 data bits, 1 stop bit, the '1') FE88 [04] 1004 217 br25: BSET 0,DDRA ; Serial Out (= '0') 218 FE8A [03] 2000 219 BRA br19 ; wait loop from here to br25. start from X=0 (256 loops) FE8C [03] 5BFA 220 br19: DBNZX br25 ; 256*10 = 2560 cycles = 1041us = 10 bits 221 FE8E [04] 1104 222 BCLR 0,DDRA ; Serial In (makes Serial Out high) FE90 [02] A702 223 AIS #2 ; pop the return address, we will be branching back FE92 [04] C6FFFF 224 LDA $FFFF ; return with low byte of START address ($00) FE95 [03] 2098 225 BRA GETCMD 226 *----------------------------------------- 227 * Get a Character. 228 * If it's a BREAK, send back a BREAK and go back to the start of COMMAND 229 * Otherwise, echo the character and return with the data in ACC 230 GETCHAR: FE97 [05] 0000FD 231 BRSET 0,PORTA,GETCHAR ; wait for Serial low FE9A [04] AD32 232 BSR GetBit ; This gets a serial bit and returns it in Carry Flag; 233 ; it does not change DDRA 234 * The first bit is the Start Bit FE9C [03] 25F9 235 BCS GETCHAR FE9E [02] A680 236 LDA #$80 ; this gets rotated into Carry after 8 shifts FEA0 [04] AD2C 237 br20: BSR GetBit ; This gets a serial bit and returns it in Carry Flag; 238 ; it does not change DDRA FEA2 [01] 46 239 RORA ; shift the Carry into the data byte FEA3 [01] 9D 240 NOP gp32mon.ASM Assembled with CASM08Z 2/5/03 8:34:07 PM PAGE 7 FEA4 [03] 24FA 241 BCC br20 ; we have gotten 8 bits FEA6 [04] AD26 242 BSR GetBit ; This gets a serial bit and returns it in Carry Flag; 243 ; it does not change DDRA, a '1' at this point 244 ; means it's a BREAK character FEA8 [03] 24D7 245 BCC SENDBREAK 246 * SENDBREAK ends with BRA GETCMD, ACC contains low byte of start vector = $00; 247 * and with PA0 as in input 248 * Continue on to echo the byte 249 *----------------------------------- 250 * Returns with PA0 as an output 251 SENDCHAR: FEAA [02] 89 252 PSHX FEAB [02] 87 253 PSHA FEAC [02] A60A 254 LDA #$0A ; we are doing 10 (the last two are stop bits) 255 FEAE [05] 0100FD 256 br22: BRCLR 0,PORTA,br22 ; wait for Serial In to go high 257 FEB1 [02] AEA9 258 LDX #$0A9 ; wait FEB3 [03] 5BFE 259 br23: DBNZX br23 260 FEB5 [01] 99 261 SEC ; Carry bit "sticks" and make the stop bits FEB6 [03] 2009 262 BRA br24 263 FEB8 [05] 9E6601 264 br28: ROR 1,SP ; data is on the Stack 5 FEBB [03] 2404 265 BCC br24 ; 3 FEBD [04] 1104 266 BCLR 0,DDRA ; Serial In (1) FEBF [03] 2004 267 BRA br26 268 FEC1 [04] 1004 269 br24: BSET 0,DDRA ; Serial Out (0) 4 FEC3 [03] 2000 270 BRA br26 ; 3 271 272 *&Time 273 * At 2.4576 MHz we need to have a total of 256 cycles between bits, including 274 * 20 cycles of overhead 275 * wait 3*79 = 237 cycles; 237 + 20 = 257; 257/2.4576=104.5 us FEC5 [02] AE4F 276 br26: LDX #$4F ; 2 FEC7 [03] 5BFE 277 br27: DBNZX br27 ; 3 278 279 * At 8 MHz we need to have a total of 833 cycles between bits, including 280 * 20 cycles of overhead. (813/3=271cycles, so we will add a NOP. gp32mon.ASM Assembled with CASM08Z 2/5/03 8:34:07 PM PAGE 8 281 * (813/4=203.25) 282 * wait 4*203 cycles = 812; 812+20=832; 832/8 = 104.0 us 283 *br26: LDX #$4F ; 2 284 *br27: NOP ; 1 285 * DBNZX br27 ; 3 286 287 FEC9 [03] 4BED 288 DBNZA br28 ; next bit 3 FECB [02] 86 289 PULA FECC [02] 88 290 PULX FECD [04] 81 291 RTS ; returns with PA0 as an output 292 *------------------------------------------ 293 * This gets a serial bit and returns it in Carry Flag; does not change DDRA FECE [02] 89 294 GetBit: PSHX ; 2 FECF [02] 87 295 PSHA ; 2 296 297 *&Time FED0 [02] A610 298 LDA #16 ; 2 2.4576 MHz -> 16 8 MHz -> 56 FED2 [02] AE17 299 LDX #23 ; 2 2.4576 MHz -> 23 8 MHz -> 81 300 * Timed: 301 * 17+10*X = 17 + 10*23 = 247 cycles = 100 us (one bit 104) [2.4576 MHz] 302 * 17+10*X = 17 + 10*81 = 827 (832) cycles = 103 us (one bit) [8 MHz] 303 * ACC starts out = 16. If fewer than 16 samples are '0' it will remain 304 * positive. If more than 16 samples are '1' it will be negative. 305 * Apparantly, Motorola's factory is very noisy and the noise is more likely 306 * to change '0's to '1's. FED4 [05] 010000 307 br30: BRCLR 0,PORTA,br29 ; } 5 sets Carry according to Serial bit FED7 [02] A200 308 br29: SBC #$0 ; } 2 FED9 [03] 5BF9 309 DBNZX br30 ; } 3 310 FEDB [01] 49 311 ROLA ; 1 rotates the sign bit into Carry 312 FEDC [02] 86 313 PULA ; 2 FEDD [02] 88 314 PULX ; 2 FEDE [04] 81 315 RTS ; 4 316 *========================================================= FEFB 317 ORG $FEFB FEFB 04 318 FCB $04 319 *========================================================= 320 *Monitor ROM SWI and Break Vector gp32mon.ASM Assembled with CASM08Z 2/5/03 8:34:07 PM PAGE 9 FEFC 321 ORG $FEFC 322 FEFC FE28 323 FDB SWIVEC ; Monitor ROM SWI and Break Vector FEFE FF00 324 FDB START ; Monitor ROM Reset Vector 325 *================================================================== 326 * End of Monitor Functions 327 ******************************************************************* 328 ******************************************************************* 329 * Monitor Initiation/Check Security Code 330 *================================================================== FF00 331 ORG $FF00 332 FF00 [03] 2F17 333 START: BIH br31 ; If IRQ is high, do direct clock 334 335 * Set up the PLL 336 * Monitor Mode uses a VCO clock of 9.8304 MHz, Bus frequency = 2.4576 MHz. FF02 [03] 3F36 337 CLR PCTL ; PLL Control -> P,E FF04 [04] 1036 338 BSET 0,PCTL ; PCTL = $01 FF06 [04] 1038 339 BSET 0,PMSH ; PLL Multiplier Select High byte FF08 [02] A62C 340 LDA #$2C FF0A [03] B739 341 STA PMSL ; PLL Multiplier Select Low byte FF0C [02] A680 342 LDA #$80 FF0E [03] B73A 343 STA PMRS ; PLL VCO Range Select ->L FF10 [04] 1A36 344 BSET 5,PCTL FF12 [04] 1E37 345 BSET 7,PBWC ; PLL Bandwidth Control 346 FF14 [05] 0D37FD 347 loop1: BRCLR 6,PBWC,loop1 ; wait for PLL to stabilize FF17 [04] 1836 348 BSET 4,PCTL ; select VCO clock 349 *---------------------------------- 350 * Clock is set up, either Direct External Clock or PLL FF19 [02] A7FA 351 br31: AIS #-6 ; reserve some stack space (why?) FF1B [04] 1100 352 BCLR 0,PORTA ; used for SENDCHAR later on FF1D [04] 6EFF40 353 MOV #$0FF,sflag ; security flag FF20 [03] 45FFF6 354 LDHX #$0FFF6 ; first address of security code FF23 [05] 0E0002 355 BRSET 7,PORTA,br32 ; When PA7 = 1 it will use parallel data input FF26 [04] 1F40 356 BCLR 7,sflag ; PA7 = 0 for serial data input 357 *---------------------------------- 358 * If it is using parallel data input it will read the security data from 359 * Port A and skip GETCHAR. It does not signal the outside world when it is 360 * reading the port. Apparently data must be presented to Port A by using gp32mon.ASM Assembled with CASM08Z 2/5/03 8:34:07 PM PAGE 10 361 * rigorous timing. FF28 [04] 51FE1A 362 br32: CBEQX #$0FE,INITOUT1 ; compare XReg, no flags affected FF2B [03] B600 363 LDA PORTA ; parallel data input FF2D [05] 0E4003 364 BRSET 7,sflag,br34 ; skip GETCHAR if using parallel data input 365 FF30 [05] CDFE97 366 JSR GETCHAR ; Returns with a character in ACC 367 FF33 [01] 9D 368 br34: NOP FF34 [04] 71F2 369 CBEQ X+,br32 ; compare ACC to iX+, no flags affected 370 *---------------------------------- 371 * something didn't match, but don't tell anyone yet FF36 [04] 51FE12 372 br41: CBEQX #$0FE,INITOUT2 ; compare XReg, no flags affected FF39 [03] B600 373 LDA PORTA ; sets Z,N (N=PA7) FF3B [05] 0E4003 374 BRSET 7,sflag,br40 ; skip GETCHAR if using parallel data input 375 FF3E [05] CDFE97 376 JSR GETCHAR ; Returns with a character in ACC 377 FF41 [02] AF01 378 br40: AIX #1 ; no flags affected FF43 [03] 20F1 379 BRA br41 380 *---------------------------------- 381 INITOUT1: FF45 [02] AEFF 382 LDX #$0FF ; we left Xregs at $FFFE, this makes it $FFFF FF47 [01] 9C 383 RSP FF48 [03] CCFE20 384 JMP ENTRY1 ; we passed Security 385 386 INITOUT2: FF4B [04] 1D40 387 BCLR 6,sflag ; Record that Security has failed FF4D [02] AEFF 388 LDX #$0FF FF4F [01] 9C 389 RSP FF50 [03] CCFE21 390 JMP ENTRY2 ; we did not pass Security 391 *=============================================================== 392 * End of Motorola Monitor Code 393 *=============================================================== 394 *=============================================================== 395 * This is so it can be assembled FFFC 396 ORG $FFFC FFFC FE28 397 SWI_VEC FDB SWIVEC ; Software Interrupt FFFE FF00 398 RESET_VEC FDB START ; Beginning of program on reset 399 *============================================================ 400 gp32mon.ASM Assembled with CASM08Z 2/5/03 8:34:07 PM PAGE 11 Symbol Table BCS 0004 BR1 FE27 BR10 FE4B BR12 FE5A BR13 FE65 BR14 FE62 BR15 FE4C BR17 FE80 BR18 FE78 BR18A FE86 BR19 FE8C BR20 FEA0 BR22 FEAE BR23 FEB3 BR24 FEC1 BR25 FE88 BR26 FEC5 BR27 FEC7 BR28 FEB8 BR29 FED7 BR30 FED4 BR31 FF19 BR32 FF28 BR34 FF33 BR4 FE3C BR40 FF41 BR41 FF36 BR5 FE5C BR7 FE50 BRKH FE09 BRKL FE0A BRKSCR FE0B CHAR 0042 CHECKBREAK FE75 CONFIG1 001F CONFIG2 001E COUNT 004D gp32mon.ASM Assembled with CASM08Z 2/5/03 8:34:07 PM PAGE 12 DADDRESS 0046 DATA 0041 DDRA 0004 DDRB 0005 DDRC 0006 DDRD 0007 DDRE 000C ENSCI 0006 ENTRY1 FE20 ENTRY2 FE21 FLBPR FF7E FLCR FE08 FLTCR FE07 GETBIT FECE GETCHAR FE97 GETCMD FE2F INITOUT1 FF45 INITOUT2 FF4B INT1 FE04 INT2 FE05 INT3 FE06 LATCH 0004 LCDADR 004C LCDEN 0005 LCDRS 0006 LCDRW 0007 LOOP1 FF14 LVISR FE0C MADDRESS 0043 MDATA 0045 NCS0 0000 NCS1 0001 NRD 0003 NWR 0002 PAPUP 000D PB0 0000 PB1 0001 PB2 0002 PB3 0003 PB4 0004 gp32mon.ASM Assembled with CASM08Z 2/5/03 8:34:07 PM PAGE 13 PB5 0005 PB6 0006 PBWC 0037 PCPUP 000E PCTL 0036 PDPUP 000F PLLON 0005 PMDS 003B PMRS 003A PMSH 0038 PMSL 0039 PORTA 0000 PORTB 0001 PORTC 0002 PORTD 0003 PORTE 0008 RAMSTART 0040 RE 0002 READSP FE6D RESET_VEC FFFE ROMSTART B000 RX 0001 SAVEACC 004B SAVEX 004A SBFCR FE03 SBSR FE00 SCBR 0019 SCC1 0013 SCC2 0014 SCC3 0015 SCDR 0018 SCRF 0005 SCS1 0016 SCS2 0017 SENDBREAK FE81 SENDCHAR FEAA SFLAG 0040 SPCR 0010 SPDR 0012 SPE 0001 gp32mon.ASM Assembled with CASM08Z 2/5/03 8:34:07 PM PAGE 14 SPSCR 0011 SRSR FE01 START FF00 SUBAR FE02 SWEN 0004 SWIVEC FE28 SWI_VEC FFFC T1CH0H 0026 T1CH0L 0027 T1CH1H 0029 T1CH1L 002A T1CNTH 0021 T1CNTL 0022 T1MODH 0023 T1MODL 0024 T1SC 0020 T1SC0 0025 T1SC1 0028 T2CH0H 0031 T2CH0L 0032 T2CH1H 0034 T2CH1L 0035 T2CNTH 002C T2CNTL 002D T2MODH 002E T2MODL 002F T2SC 002B T2SC0 0030 T2SC1 0033 TC 0006 TE 0003 TEMP 0048 TEMPL 0049 TOF 0007 TOIE 0006 TRST 0004 TSTOP 0005 TX 0000 VECTORS FFDC