A51 MACRO ASSEMBLER BAL 21/07/99 16:17:43 PAGE 1 DOS MACRO ASSEMBLER A51 V5.28m OBJECT MODULE PLACED IN BAL.OBJ ASSEMBLER INVOKED BY: C:\ANCHOR\KEIL2K\BIN\A51.EXE BAL.A51 RB(0) DB EP LOC OBJ LINE SOURCE 1 NAME ButtonsAndLights 2 3 $INCLUDE(..\Declare.A51) =1 4 ; This module declares the variables and constants used in the examples =1 5 ; It is common to all of the examples =1 6 ; =1 7 ; Declare Special Function Registers used 00A8 =1 8 EI DATA 0A8H 00E8 =1 9 EIE DATA 0E8H ; EZ-USB specific 0091 =1 10 EXIF DATA 091H ; EZ-USB specific 00D8 =1 11 EICON DATA 0D8H ; EZ-USB specific 0092 =1 12 PageReg DATA 092H ; EZ-USB specific, used with MOVX @Ri 0086 =1 13 DPS DATA 086H ; EZ-USB specific, used with dual data pointers =1 14 ; =1 15 ; "External" memory locations used, EZ-USB specific =1 16 ; Note that most of these variables are in Page 7FH 7FE8 =1 17 SETUPDAT EQU 07FE8H 7FD4 =1 18 SUDPTR EQU 07FD4H 7FB4 =1 19 EP0Control EQU 07FB4H 7F00 =1 20 EP0InBuffer EQU 07F00H 7EC0 =1 21 EP0OutBuffer EQU 07EC0H ; Not in Page 7FH 7E80 =1 22 EP1InBuffer EQU 07E80H ; Not in Page 7FH 7FB5 =1 23 IN0ByteCount EQU 07FB5H 7FC5 =1 24 Out0ByteCount EQU 07FC5H 7FB7 =1 25 IN1ByteCount EQU 07FB7H 7FAC =1 26 IN07IEN EQU 07FACH 7FA9 =1 27 IN07IRQ EQU 07FA9H 7FAD =1 28 OUT07IEN EQU 07FADH 7FAA =1 29 OUT07IRQ EQU 07FAAH 7FAE =1 30 USBIEN EQU 07FAEH 7FAB =1 31 USBIRQ EQU 07FABH 7FD6 =1 32 USBControl EQU 07FD6H 7FA6 =1 33 I2CData EQU 07FA6H 7FA5 =1 34 I2CControl EQU 07FA5H 7F99 =1 35 PortA_PINS EQU 07F99H 7F9A =1 36 PortB_PINS EQU 07F9AH 7F93 =1 37 PortA_Config EQU 07F93H 7F94 =1 38 PortB_Config EQU 07F94H 7F96 =1 39 PortA_OUT EQU 07F96H 7F9C =1 40 PortA_OE EQU 07F9CH 7F9D =1 41 PortB_OE EQU 07F9DH =1 42 ; =1 43 ; Byte Variables =1 44 ---- =1 45 DSEG AT 20H 0020 =1 46 FLAGS: DS 1 ; This register is bit-addressable =1 47 ; Bit Variables 0000 =1 48 Configured EQU FLAGS.0 ; Is this device configured 0001 =1 49 STALL EQU FLAGS.1 ; Need to STALL endpoint 0 0002 =1 50 SendData EQU FLAGS.2 ; Need to send data to PC Host 0003 =1 51 IsDescriptor EQU FLAGS.3 ; Enable a shortcut reply =1 52 ; 0021 =1 53 MonitorSpace: DS 1FH ; Used by Dscope 0040 =1 54 Temp: DS 1 ; A temporary working register 0041 =1 55 Idle_Time: DS 1 ; The time the PC host wants us to wait 0042 =1 56 Expired_Time: DS 1 ; A downcounter for timed Reports 0043 =1 57 ReplyBuffer: DS 3 ; First byte is Count =1 58 ; A51 MACRO ASSEMBLER BAL 21/07/99 16:17:43 PAGE 2 =1 59 ; Declare the specific variables used by each of the examples 0046 =1 60 Overlay EQU $ 0046 =1 61 Old_Buttons: DS 1 ; Used by BAL: stores current button position 0047 =1 62 LEDstrobe: DS 1 ; Used by BAL: strobe one LED on at a time 0048 =1 63 LEDvalue: DS 1 ; Used by BAL: stores current LED value 0049 =1 64 Msec_Counter: DS 1 ; Used by BAL: counts up to 4 msec =1 65 0046 =1 66 ORG Overlay ; Overlay the variables (only one set in use at any one tim e) 0046 =1 67 I2CDataByte: DS 1 ; Used by I2C: keep a local copy of data read from I2C bus =1 68 0046 =1 69 ORG Overlay 0046 =1 70 LightValues: DS 6 ; Used by LP: local buffer for light brightness =1 71 0046 =1 72 ORG Overlay 0046 =1 73 LEDBuffer: DS 42 ; Used by RB: local buffer for reader board =1 74 ; 75 $INCLUDE(..\Vectors.A51) =1 76 ; This module is common to all of the examples. =1 77 ; It contains all of the interrupt vector declarations and =1 78 ; the first level interrupt servicing (register save, call subroutine, =1 79 ; clear interrupt source, restore registers, return) =1 80 ; Suspend and Resume are handled totally in this module =1 81 ; =1 82 ; A Reset sends us to Program space location 0 ---- =1 83 CSEG AT 0 ; Code space =1 84 USING 0 ; Reset forces Register Bank 0 0000 0203B1 =1 85 LJMP Reset =1 86 ; =1 87 ; The interrupt vector table is also located here =1 88 ; EZ-USB has two levels of USB interrupts: =1 89 ; 1-the main level is described in this table (at ORG 43H) =1 90 ; 2-there are 21 sources of USB interrupts and these are described in USB_ISR =1 91 ; This means that two levels of acknowledgement and clearing will be required =1 92 ; LJMP INT0_ISR ; Features not used are commented out =1 93 ; ORG 0BH =1 94 ; LJMP Timer0_ISR =1 95 ; ORG 13H =1 96 ; LJMP INT1_ISR =1 97 ; ORG 1BH =1 98 ; LJMP Timer1_ISR =1 99 ; ORG 23H =1 100 ; LJMP UART0_ISR =1 101 ; ORG 2BH =1 102 ; LJMP Timer2_ISR =1 103 ; ORG 33H =1 104 ; LJMP WakeUp_ISR =1 105 ; ORG 3BH =1 106 ; LJMP UART1_ISR 0043 =1 107 ORG 43H 0043 020100 =1 108 LJMP USB_ISR ; Auto Vector will replace byte 45H =1 109 ; ORG 4BH =1 110 ; LJMP I2C_ISR =1 111 ; ORG 53H =1 112 ; LJMP INT4_ISR =1 113 ; ORG 5BH =1 114 ; LJMP INT5_ISR =1 115 ; ORG 63H =1 116 ; LJMP INT6_ISR =1 117 00E0 =1 118 ORG 0E0H ; Keep out of the way of dScope monitor =1 119 ; If you are not using dScope then this memory hole =1 120 ; may be used for useful routines. 0100 =1 121 ORG 100H 0100 02013C =1 122 USB_ISR:LJMP SUDAV_ISR 0103 00 =1 123 DB 0 ; Pad entries to 4 bytes A51 MACRO ASSEMBLER BAL 21/07/99 16:17:43 PAGE 3 0104 020158 =1 124 LJMP SOF_ISR 0107 00 =1 125 DB 0 0108 020118 =1 126 LJMP SUTOK_ISR 010B 00 =1 127 DB 0 010C 020129 =1 128 LJMP Suspend_ISR 010F 00 =1 129 DB 0 0110 020120 =1 130 LJMP USBReset_ISR 0113 00 =1 131 DB 0 0114 020118 =1 132 LJMP Reserved 0117 00 =1 133 DB 0 =1 134 ; LJMP EP0In_ISR ; Endpoint Interrupts are not used in these examples =1 135 ; DB 0 ; Comment out features not used =1 136 ; LJMP EP0Out_ISR =1 137 ; DB 0 =1 138 ; LJMP EP1In_ISR =1 139 ; DB 0 =1 140 ; LJMP EP1Out_ISR =1 141 ; DB 0 =1 142 ; LJMP EP2In_ISR =1 143 ; DB 0 =1 144 ; LJMP EP2Out_ISR =1 145 ; DB 0 =1 146 ; LJMP EP3In_ISR =1 147 ; DB 0 =1 148 ; LJMP EP3Out_ISR =1 149 ; DB 0 =1 150 ; LJMP EP4In_ISR =1 151 ; DB 0 =1 152 ; LJMP EP4Out_ISR =1 153 ; DB 0 =1 154 ; LJMP EP5In_ISR =1 155 ; DB 0 =1 156 ; LJMP EP5Out_ISR =1 157 ; DB 0 =1 158 ; LJMP EP6In_ISR =1 159 ; DB 0 =1 160 ; LJMP EP6Out_ISR =1 161 ; DB 0 =1 162 ; LJMP EP7In_ISR =1 163 ; DB 0 =1 164 ; LJMP EP7Out_ISR =1 165 ; End of Interrupt Vector tables =1 166 =1 167 ; When a feature is used insert the required interrupt processing here =1 168 ; The example use only used Endpoints 0 and 1 and also SOF for timing 0118 =1 169 Reserved: 0118 =1 170 INT0_ISR: 0118 =1 171 Timer0_ISR: 0118 =1 172 INT1_ISR: 0118 =1 173 Timer1_ISR: 0118 =1 174 UART0_ISR: 0118 =1 175 Timer2_ISR: 0118 =1 176 UART1_ISR: 0118 =1 177 I2C_ISR: 0118 =1 178 INT4_ISR: 0118 =1 179 INT5_ISR: 0118 =1 180 INT6_ISR: 0118 =1 181 SUTOK_ISR: 0118 =1 182 EP0In_ISR: 0118 =1 183 EP0Out_ISR: 0118 =1 184 EP1In_ISR: 0118 =1 185 EP1Out_ISR: 0118 =1 186 EP2In_ISR: 0118 =1 187 EP2Out_ISR: 0118 =1 188 EP3In_ISR: 0118 =1 189 EP3Out_ISR: A51 MACRO ASSEMBLER BAL 21/07/99 16:17:43 PAGE 4 0118 =1 190 EP4In_ISR: 0118 =1 191 EP4Out_ISR: 0118 =1 192 EP5In_ISR: 0118 =1 193 EP5Out_ISR: 0118 =1 194 EP6In_ISR: 0118 =1 195 EP6Out_ISR: 0118 =1 196 EP7In_ISR : 0118 =1 197 EP7Out_ISR: 0118 =1 198 Not_Used: ; Should not get any of these 0118 32 =1 199 RETI =1 200 0119 =1 201 ClearINT2: ; Tell the hardware that we're done 0119 E591 =1 202 MOV A, EXIF 011B C2E4 =1 203 CLR ACC.4 ; Clear the Interrupt 2 bit 011D F591 =1 204 MOV EXIF, A 011F 22 =1 205 RET =1 206 0120 =1 207 USBReset_ISR: ; Bus has been Reset, move to DEFAULT state 0120 C0E0 =1 208 PUSH ACC 0122 C200 =1 209 CLR Configured 0124 3119 =1 210 CALL ClearINT2 =1 211 ; No need to clear source of interrupt 0126 D0E0 =1 212 POP ACC 0128 32 =1 213 RETI =1 214 0129 =1 215 Suspend_ISR: ; SIE detected an Idle bus 0129 C0E0 =1 216 PUSH ACC 012B E587 =1 217 MOV A, PCON 012D 4401 =1 218 ORL A, #1 012F F587 =1 219 MOV PCON, A ; Go to sleep! 0131 00 =1 220 NOP 0132 00 =1 221 NOP ; Wake up here due to a USBResume 0133 00 =1 222 NOP 0134 3119 =1 223 CALL ClearINT2 0136 D0E0 =1 224 POP ACC 0138 32 =1 225 RETI =1 226 0139 =1 227 WakeUp_ISR: ; Not using external WAKEUP in these examples =1 228 ; So this must be due to a USBResume 0139 C2DC =1 229 CLR EICON.4 ; Clear the wakeup interrupt source 013B 32 =1 230 RETI =1 231 013C =1 232 SUDAV_ISR: ; A Setup packet has been received 013C C0D0 =1 233 PUSH PSW ; Save Registers before the service routine 013E C0E0 =1 234 PUSH ACC 0140 C082 =1 235 PUSH DPL 0142 C083 =1 236 PUSH DPH 0144 120169 =1 237 CALL ServiceSetupPacket 0147 3119 =1 238 CALL ClearINT2 =1 239 ; Clear the source of the interrupt 0149 7401 =1 240 MOV A, #00000001b 014B 907FAB =1 241 ExitISR:MOV DPTR, #USBIRQ 014E F0 =1 242 MOVX @DPTR, A 014F D083 =1 243 POP DPH ; Restore Registers 0151 D082 =1 244 POP DPL 0153 D0E0 =1 245 POP ACC 0155 D0D0 =1 246 POP PSW 0157 32 =1 247 RETI =1 248 0158 =1 249 SOF_ISR: ; A Start-Of-Frame packet has been received 0158 C0D0 =1 250 PUSH PSW ; Save Registers before the service routine 015A C0E0 =1 251 PUSH ACC 015C C082 =1 252 PUSH DPL 015E C083 =1 253 PUSH DPH 0160 120428 =1 254 CALL ServiceTimerRoutine 0163 3119 =1 255 CALL ClearINT2 A51 MACRO ASSEMBLER BAL 21/07/99 16:17:43 PAGE 5 =1 256 ; Clear the source of the interrupt 0165 7402 =1 257 MOV A, #00000010b 0167 80E2 =1 258 JMP ExitISR =1 259 =1 260 261 $INCLUDE(..\USB_INT.A51) =1 262 ; This module is common to all of the examples. =1 263 ; It services USB Requests from the SIE. =1 264 ; Interpretation of the Output Reports is handled by MAIN =1 265 ; ---- =1 266 CSEG 0169 =1 267 ServiceSetupPacket: 0169 907FE8 =1 268 MOV DPTR, #SETUPDAT ; Point to Setup Packet data 016C E0 =1 269 MOVX A, @DPTR ; Get the RequestType 016D A2E7 =1 270 MOV C, ACC.7 ; Bit 7 = 1 means IO device needs to send data to P C Host 016F 9202 =1 271 MOV SendData, C 0171 545C =1 272 ANL A, #01011100b ; IF RequestType[6.4.3.2] = 1 THEN goto BadRequest 0173 7051 =1 273 JNZ BadRequest 0175 E0 =1 274 MOVX A, @DPTR ; IF RequestType[1&0] = 1 THEN goto BadRequest 0176 A2E0 =1 275 MOV C, ACC.0 0178 82E1 =1 276 ANL C, ACC.1 017A 404A =1 277 JC BadRequest 017C 30E502 =1 278 JNB ACC.5, NotB5 ; IF RequestType[5] = 1 THEN RequestType[1,0] = [1, 1] 017F 7403 =1 279 MOV A, #00000011b 0181 5403 =1 280 NotB5: ANL A, #00000011b ; Set CommandIndex[5,4] = RequestType[1,0] 0183 C4 =1 281 SWAP A 0184 F540 =1 282 MOV Temp, A ; Save HI nibble of CommandIndex =1 283 ; Set CommandIndex[3,0] = Request[3,0] 0186 A3 =1 284 INC DPTR ; Point to Request 0187 E0 =1 285 MOVX A, @DPTR 0188 540F =1 286 ANL A, #00001111b ; Only 13 are defined today, handle in table 018A 4540 =1 287 ORL A, Temp 018C 1201D5 =1 288 CALL CorrectSubroutine ; goto CommandTable(CommandIndex) =1 289 ; Returns STALL=1 if a stall is required 018F 200134 =1 290 JB STALL, BadRequest 0192 300218 =1 291 JNB SendData, HandShake 0195 200320 =1 292 JB IsDescriptor, LoadSUDPTR; EZ-USB has a short cut for descriptors =1 293 ; Send data in ReplyBuffer 0198 907F02 =1 294 MOV DPTR, #EP0InBuffer+2 019B 7846 =1 295 MOV R0, #ReplyBuffer+3 019D 754003 =1 296 MOV Temp, #3 ; Copy maximum byte count 01A0 E6 =1 297 CopyRB: MOV A, @R0 01A1 F0 =1 298 MOVX @DPTR, A 01A2 1582 =1 299 DEC DPL 01A4 18 =1 300 DEC R0 01A5 D540F8 =1 301 DJNZ Temp, CopyRB 01A8 E6 =1 302 MOV A, @R0 ; Get real byte count 01A9 =1 303 SendEP0InBuffer: 01A9 907FB5 =1 304 MOV DPTR, #In0ByteCount 01AC =1 305 StartXfer: 01AC F0 =1 306 MOVX @DPTR, A ; This write initiates the transfer 01AD =1 307 HandShake: ; Handshake with host 01AD 754002 =1 308 MOV Temp, #00000010b ; Set HSNAK to tell the SIE that we're done 01B0 =1 309 SetEP0Control: 01B0 907FB4 =1 310 MOV DPTR, #EP0Control 01B3 E0 =1 311 MOVX A, @DPTR 01B4 4540 =1 312 ORL A, Temp 01B6 F0 =1 313 MOVX @DPTR, A 01B7 22 =1 314 RET 01B8 =1 315 LoadSUDPTR: ; Send the data pointed to by DPTR 01B8 858240 =1 316 MOV Temp, DPL 01BB E583 =1 317 MOV A, DPH 01BD 907FD4 =1 318 MOV DPTR, #SUDPTR 01C0 F0 =1 319 MOVX @DPTR, A A51 MACRO ASSEMBLER BAL 21/07/99 16:17:43 PAGE 6 01C1 E540 =1 320 MOV A, Temp 01C3 A3 =1 321 INC DPTR 01C4 80E6 =1 322 JMP StartXfer 01C6 =1 323 BadRequest: ; Invalid Request was received 01C6 754003 =1 324 MOV Temp, #00000011b ; Set EP0STALL and HSNAK 01C9 80E5 =1 325 JMP SetEP0Control =1 326 01CB =1 327 NextDPTR: ; Returns (DPTR + byte DPTR is pointing to) 01CB E0 =1 328 MOVX A, @DPTR 01CC =1 329 BumpDPTR: ; Returns (DPTR + ACC) 01CC 2582 =1 330 ADD A, DPL 01CE F582 =1 331 MOV DPL, A 01D0 5002 =1 332 JNC Skip 01D2 0583 =1 333 INC DPH ; Need 16 bit arithmetic here 01D4 22 =1 334 Skip: RET =1 335 01D5 =1 336 CorrectSubroutine: ; Jump to the subroutine that DPTR is pointing to 01D5 9001FA =1 337 MOV DPTR, #CommandTable 01D8 31CC =1 338 CALL BumpDPTR ; Point to entry 01DA E0 =1 339 MOVX A, @DPTR ; Get the offset 01DB 9001FA =1 340 MOV DPTR, #CommandTable 01DE 31CC =1 341 CALL BumpDPTR ; Get the routine address 01E0 C082 =1 342 PUSH DPL ; Create a RETURN address on stack 01E2 C083 =1 343 PUSH DPH ; Note: JMP @A+DPTR not used since A, DPTR needed 01E4 7845 =1 344 MOV R0, #ReplyBuffer+2 01E6 E4 =1 345 CLR A 01E7 F6 =1 346 MOV @R0, A ; Clear ReplyBuffer 01E8 18 =1 347 DEC R0 01E9 F6 =1 348 MOV @R0, A 01EA 18 =1 349 DEC R0 01EB 7601 =1 350 MOV @R0, #1 ; Default non-descriptor reply 01ED 907FEA =1 351 MOV DPTR, #SETUPDAT+2 ; Point to LOW(wValue) 01F0 E0 =1 352 MOVX A, @DPTR ; Many of the routines need these 01F1 F5F0 =1 353 MOV B, A ; LOW(wValue) in B 01F3 A3 =1 354 INC DPTR 01F4 E0 =1 355 MOVX A, @DPTR ; HIGH(wValue) in A 01F5 C201 =1 356 CLR STALL 01F7 C203 =1 357 CLR IsDescriptor 01F9 22 =1 358 RET ; Go to service routine =1 359 =1 360 ; Since the table only contains byte offsets, it is important that all these routines are =1 361 ; within one page (100H) of CommandTable =1 362 ; 01FA =1 363 CommandTable: =1 364 ; First 16 commands are for the Device 01FA 6D =1 365 DB Device_Get_Status - CommandTable 01FB 40 =1 366 DB Device_Clear_Feature - CommandTable 01FC 40 =1 367 DB Invalid - CommandTable 01FD 40 =1 368 DB Device_Set_Feature - CommandTable 01FE 40 =1 369 DB Invalid - CommandTable 01FF 40 =1 370 DB Invalid - CommandTable ; SIE implements Device_Set_Address 0200 81 =1 371 DB Get_Descriptor - CommandTable 0201 40 =1 372 DB Set_Descriptor - CommandTable 0202 6A =1 373 DB Get_Configuration - CommandTable 0203 74 =1 374 DB Set_Configuration - CommandTable 0204 40 =1 375 DB Invalid - CommandTable 0205 40 =1 376 DB Invalid - CommandTable 0206 40 =1 377 DB Invalid - CommandTable 0207 40 =1 378 DB Invalid - CommandTable 0208 40 =1 379 DB Invalid - CommandTable 0209 40 =1 380 DB Invalid - CommandTable =1 381 ; Next 16 commands are for the Interface 020A 71 =1 382 DB Interface_Get_Status - CommandTable 020B 40 =1 383 DB Interface_Clear_Feature - CommandTable 020C 40 =1 384 DB Invalid - CommandTable 020D 40 =1 385 DB Interface_Set_Feature - CommandTable A51 MACRO ASSEMBLER BAL 21/07/99 16:17:43 PAGE 7 020E 40 =1 386 DB Invalid - CommandTable 020F 40 =1 387 DB Invalid - CommandTable 0210 A5 =1 388 DB Get_Class_Descriptor - CommandTable 0211 40 =1 389 DB Set_Class_Descriptor - CommandTable 0212 40 =1 390 DB Invalid - CommandTable 0213 40 =1 391 DB Invalid - CommandTable 0214 40 =1 392 DB Get_Interface - CommandTable 0215 40 =1 393 DB Set_Interface - CommandTable 0216 40 =1 394 DB Invalid - CommandTable 0217 40 =1 395 DB Invalid - CommandTable 0218 40 =1 396 DB Invalid - CommandTable 0219 40 =1 397 DB Invalid - CommandTable =1 398 ; Next 16 commands are for the Endpoint 021A 71 =1 399 DB Endpoint_Get_Status - CommandTable 021B 42 =1 400 DB Endpoint_Clear_Feature - CommandTable 021C 40 =1 401 DB Invalid - CommandTable 021D 40 =1 402 DB Endpoint_Set_Feature - CommandTable 021E 40 =1 403 DB Invalid - CommandTable 021F 40 =1 404 DB Invalid - CommandTable 0220 40 =1 405 DB Invalid - CommandTable 0221 40 =1 406 DB Invalid - CommandTable 0222 40 =1 407 DB Invalid - CommandTable 0223 40 =1 408 DB Invalid - CommandTable 0224 40 =1 409 DB Invalid - CommandTable 0225 40 =1 410 DB Invalid - CommandTable 0226 40 =1 411 DB Endpoint_Sync_Frame - CommandTable 0227 40 =1 412 DB Invalid - CommandTable 0228 40 =1 413 DB Invalid - CommandTable 0229 40 =1 414 DB Invalid - CommandTable =1 415 ; Next 16 commands are Class Requests 022A 40 =1 416 DB Invalid - CommandTable 022B 56 =1 417 DB Get_Report - CommandTable 022C 63 =1 418 DB Get_Idle - CommandTable 022D 40 =1 419 DB Get_Protocol - CommandTable 022E 40 =1 420 DB Invalid - CommandTable 022F 40 =1 421 DB Invalid - CommandTable 0230 40 =1 422 DB Invalid - CommandTable 0231 40 =1 423 DB Invalid - CommandTable 0232 40 =1 424 DB Invalid - CommandTable 0233 43 =1 425 DB Set_Report - CommandTable 0234 5D =1 426 DB Set_Idle - CommandTable 0235 40 =1 427 DB Set_Protocol - CommandTable 0236 40 =1 428 DB Invalid - CommandTable 0237 40 =1 429 DB Invalid - CommandTable 0238 40 =1 430 DB Invalid - CommandTable 0239 40 =1 431 DB Invalid - CommandTable =1 432 ; =1 433 ; Many requests are INVALID for this example 023A =1 434 Get_Protocol: ; We are not a Boot device 023A =1 435 Set_Protocol: ; We are not a Boot device 023A =1 436 Set_Descriptor: ; Our Descriptors are static 023A =1 437 Set_Class_Descriptor: ; Our Descriptors are static 023A =1 438 Set_Interface: ; We only have one Interface 023A =1 439 Get_Interface: ; We do not have an Alternate setting 023A =1 440 Device_Set_Feature: ; We have no features that can be set or cleared 023A =1 441 Interface_Set_Feature: ; We have no features that can be set or cleared 023A =1 442 Endpoint_Set_Feature: ; We have no features that can be set or cleared 023A =1 443 Device_Clear_Feature: ; We have no features that can be set or cleared 023A =1 444 Interface_Clear_Feature: ; We have no features that can be set or cleared 023A =1 445 Endpoint_Sync_Frame: ; We are not an Isonchronous device =1 446 023A =1 447 Invalid: ; Invalid Request made, STALL the Endpoint 023A D201 =1 448 SETB STALL =1 449 ; 023C =1 450 Endpoint_Clear_Feature: ; We have no features that can be set or cleared =1 451 ; A51 MACRO ASSEMBLER BAL 21/07/99 16:17:43 PAGE 8 023C 22 =1 452 Reply: RET =1 453 023D =1 454 Set_Report: ; Host wants to sent us a Report. =1 455 ; The ONLY case in this example where host sends data to us 023D 3000FA =1 456 JNB Configured, Invalid ; Need to be Configured to do this command 0240 907FC5 =1 457 MOV DPTR, #Out0ByteCount ; Enable EP0OutBuffer to receive data 0243 F0 =1 458 MOVX @DPTR, A ; Any value will do 0244 907FAA =1 459 MOV DPTR, #OUT07IRQ ; Wait for valid data in EP0OutBuffer 0247 E0 =1 460 Wait4D: MOVX A, @DPTR 0248 5401 =1 461 ANL A, #00000001b 024A 60FB =1 462 JZ Wait4D 024C F0 =1 463 MOVX @DPTR, A ; Clear the interrupt 024D 020416 =1 464 JMP ProcessOutputReport ; RETurn via this subroutine 0250 =1 465 Get_Report: ; Host wants a Report 0250 3000E7 =1 466 JNB Configured, Invalid ; Need to be Configured to do this command 0253 08 =1 467 INC R0 ; Point to ReplyBuffer(1) 0254 7618 =1 468 MOV @R0, #18H ; Reply with a recognizable (arbitary) value 0256 22 =1 469 RET 0257 =1 470 Set_Idle: ; Host wants to tell us how often we should talk 0257 3000E0 =1 471 JNB Configured, Invalid ; Need to be Configured to do this command 025A F541 =1 472 MOV Idle_Time, A 025C 22 =1 473 RET ; Handshake with host 025D =1 474 Get_Idle: ; Host must have forgotten what he told us to do 025D 3000DA =1 475 JNB Configured, Invalid ; Need to be Configured to do this command 0260 08 =1 476 INC R0 ; Point to ReplyBuffer(1) 0261 A641 =1 477 MOV @R0, Idle_Time 0263 22 =1 478 RET 0264 =1 479 Get_Configuration: 0264 3000D5 =1 480 JNB Configured, Reply =1 481 ; If configured return a 1 (via Device_Get_Status) 0267 =1 482 Device_Get_Status: ; Only two bits of Device Status are defined 0267 08 =1 483 INC R0 ; Point to ReplyBuffer(1) 0268 7601 =1 484 MOV @R0, #1 ; Bit 1=Remote Wakeup(=0), Bit 0=Self Powered(=1) 026A 22 =1 485 RET =1 486 026B =1 487 Interface_Get_Status: ; Interface Status is currently defined as 0 026B =1 488 Endpoint_Get_Status: 026B 7602 =1 489 MOV @R0, #2 026D 22 =1 490 RET 026E =1 491 Set_Configuration: ; Valid values are 0 and 1 026E E5F0 =1 492 MOV A, B ; Get LOW(wValue) 0270 6006 =1 493 JZ Deconfigured 0272 14 =1 494 DEC A 0273 70C5 =1 495 JNZ Invalid 0275 D200 =1 496 SETB Configured 0277 22 =1 497 RET 0278 =1 498 Deconfigured: 0278 C200 =1 499 CLR Configured 027A 22 =1 500 RET 027B =1 501 Get_Descriptor: ; Host wants to know who/what we are 027B D203 =1 502 SETB IsDescriptor 027D 14 =1 503 DEC A ; Valid Values are 1, 2 and 3 027E 9002C5 =1 504 MOV DPTR, #DeviceDescriptor 0281 60B9 =1 505 JZ Reply 0283 14 =1 506 DEC A 0284 9002D7 =1 507 MOV DPTR, #ConfigurationDescriptor 0287 60B3 =1 508 JZ Reply 0289 14 =1 509 DEC A 028A 70AE =1 510 JNZ Invalid =1 511 ; Request is for a String Descriptor 028C 900315 =1 512 MOV DPTR, #String0 ; Point to String 0 028F E5F0 =1 513 MOV A, B ; Get String Index 0291 =1 514 NextString: 0291 601E =1 515 JZ FixUpthenReply 0293 F540 =1 516 MOV Temp, A ; Save String Index 0295 31CB =1 517 CALL NextDPTR A51 MACRO ASSEMBLER BAL 21/07/99 16:17:43 PAGE 9 0297 E0 =1 518 MOVX A, @DPTR ; Get the String Length (= 0 means we're at Backsto p) 0298 60A0 =1 519 JZ Invalid ; Asked for a string I don't have 029A E540 =1 520 MOV A, Temp 029C 14 =1 521 DEC A 029D 80F2 =1 522 JMP NextString ; Check if we are there yet 029F =1 523 Get_Class_Descriptor: ; Valid values are 21H, 22H, 23H for Class Request 029F D203 =1 524 SETB IsDescriptor 02A1 C3 =1 525 CLR C 02A2 9421 =1 526 SUBB A, #21H 02A4 9002E9 =1 527 MOV DPTR, #HIDDescriptor 02A7 6093 =1 528 JZ Reply 02A9 14 =1 529 DEC A 02AA 9002F9 =1 530 MOV DPTR, #ReportDescriptor 02AD 608D =1 531 JZ Reply =1 532 ; DEC A ; This example does not use Physical Descriptors =1 533 ; JZ Send_Physical_Descriptor 02AF 8089 =1 534 JMP Invalid =1 535 ; =1 536 ; Error check: this MUST be on within a page of CommandTable 00B7 =1 537 WithinSamePage EQU $ - CommandTable =1 538 ; 02B1 =1 539 FixUpthenReply: ; EZ-USB Rev D has a String Descriptor bug =1 540 ; Need to fill the IN0BUF (@ 7F00H) myself 02B1 E0 =1 541 MOVX A, @DPTR ; Get the string length 02B2 FF =1 542 MOV R7, A ; Save counter 02B3 F5F0 =1 543 MOV B, A 02B5 7800 =1 544 MOV R0, #LOW(EP0InBuffer) ; PageReg = 7FH = HIGH(EP0InBuffer) 02B7 F2 =1 545 CopySD: MOVX @R0, A 02B8 08 =1 546 INC R0 02B9 A3 =1 547 INC DPTR 02BA E0 =1 548 MOVX A, @DPTR 02BB DFFA =1 549 DJNZ R7, CopySD =1 550 ; Fixup complete, get back to the program flow 02BD D0E0 =1 551 POP ACC ; Get rid of the return address 02BF D0E0 =1 552 POP ACC 02C1 E5F0 =1 553 MOV A, B ; Retrieve byte count 02C3 21A9 =1 554 JMP SendEP0InBuffer 555 $INCLUDE(DTables.A51) =1 556 ; This module declares the descriptors =1 557 ; =1 558 ; This example has one Device Descriptor with: =1 559 ; One Configuration - single IN port and single OUT port =1 560 ; One Interface - there is only one method of accessing the ports =1 561 ; One HID Descriptor - to make PC host software simpler =1 562 ; One Endpoint Descriptor - for HID Input Reports =1 563 ; One Report Descriptor - one byte IN and one byte OUT reports =1 564 ; Multiple Sting Descriptors - to aid the user =1 565 ; ---- =1 566 CSEG 02C5 =1 567 DeviceDescriptor: 02C5 1201 =1 568 DB 18, 1 ; Length, Type 02C7 0101 =1 569 DW 101H ; USB Rev 1.1 02C9 000000 =1 570 DB 0, 0, 0 ; Class, Subclass and Protocol 02CC 40 =1 571 DB 64 ; EP0 size 02CD 4242 =1 572 DW 4242H, 1, 1 ; Vendor ID, Product ID and Version 02CF 0001 02D1 0001 02D3 010200 =1 573 DB 1, 2, 0 ; Manufacturer, Product & Serial# Names 02D6 01 =1 574 DB 1 ; #Configs 02D7 =1 575 ConfigurationDescriptor: 02D7 0902 =1 576 DB 9, 2 ; Length, Type 02D9 2200 =1 577 DB LOW(ConfigLength), HIGH(ConfigLength) 02DB 010103 =1 578 DB 1, 1, 3 ; #Interfaces, Configuration#, Config. Name 02DE 80 =1 579 DB 10000000b ; Attributes = Bus Powered 02DF 32 =1 580 DB 50 ; Max. Power is 50x2 = 100mA A51 MACRO ASSEMBLER BAL 21/07/99 16:17:43 PAGE 10 02E0 =1 581 InterfaceDescriptor: 02E0 0904 =1 582 DB 9, 4 ; Length, Type 02E2 000001 =1 583 DB 0, 0, 1 ; No alternate setting, HID uses EP1 02E5 03 =1 584 DB 3 ; Class = Human Interface Device 02E6 0000 =1 585 DB 0, 0 ; Subclass and Protocol 02E8 04 =1 586 DB 4 ; Interface Name 02E9 =1 587 HIDDescriptor: 02E9 0921 =1 588 DB 9, 21H ; Length, Type 02EB 0001 =1 589 DB 0, 1 ; HID Class Specification compliance 02ED 00 =1 590 DB 0 ; Country localization (=none) 02EE 01 =1 591 DB 1 ; Number of descriptors to follow 02EF 22 =1 592 DB 22H ; And it's a Report descriptor 02F0 1C00 =1 593 DB LOW(ReportLength), HIGH(ReportLength) 02F2 =1 594 EndpointDescriptor: 02F2 0705 =1 595 DB 7, 5 ; Length, Type 02F4 81 =1 596 DB 10000001b ; Address = IN 1 02F5 03 =1 597 DB 00000011b ; Interrupt 02F6 4000 =1 598 DB 64, 0 ; Maximum packet size (this example only uses 1) 02F8 64 =1 599 DB 100 ; Poll every 0.1 seconds 0022 =1 600 ConfigLength EQU $ - ConfigurationDescriptor =1 601 02F9 =1 602 ReportDescriptor: ; Generated with HID Tool, copied to here 02F9 0600FF =1 603 DB 6, 0, 0FFH ; Usage_Page (Vendor Defined) 02FC 0901 =1 604 DB 9, 1 ; Usage (I/O Device) 02FE A101 =1 605 DB 0A1H, 1 ; Collection (Application) 0300 1901 =1 606 DB 19H, 1 ; Usage_Minimum (Button 1) 0302 2908 =1 607 DB 29H, 8 ; Usage_Maximum (Button 8) 0304 1500 =1 608 DB 15H, 0 ; Logical_Minimum (0) 0306 2501 =1 609 DB 25H, 1 ; Logical_Maximum (1) 0308 7501 =1 610 DB 75H, 1 ; Report_Size (1) 030A 9508 =1 611 DB 95H, 8 ; Report_Count (8) 030C 8102 =1 612 DB 81H, 2 ; Input (Data,Var,Abs) 030E 1901 =1 613 DB 19H, 1 ; Usage_Minimum (Led 1) 0310 2908 =1 614 DB 29H, 8 ; Usage_Maximum (Led 8) 0312 9102 =1 615 DB 91H, 2 ; Output (Data,Var,Abs) 0314 C0 =1 616 DB 0C0H ; End_Collection 001C =1 617 ReportLength EQU $-ReportDescriptor =1 618 0315 =1 619 String0: ; Declare the UNICODE strings 0315 04030904 =1 620 DB 4, 3, 9, 4 ; Only English language strings supported 0319 =1 621 String1: ; Manufacturer 0319 2C03 =1 622 DB (String2-String1),3 ; Length, Type 031B 55005300 =1 623 DB "U",0,"S",0,"B",0," ",0,"D",0,"e",0,"s",0,"i",0,"g",0,"n",0," ", 0 031F 42002000 0323 44006500 0327 73006900 032B 67006E00 032F 2000 0331 42007900 =1 624 DB "B",0,"y",0," ",0,"E",0,"x",0,"a",0,"m",0,"p",0,"l",0,"e",0 0335 20004500 0339 78006100 033D 6D007000 0341 6C006500 0345 =1 625 String2: ; Product Name 0345 2203 =1 626 DB (String3-String2),3 0347 42007500 =1 627 DB "B",0,"u",0,"t",0,"t",0,"o",0,"n",0,"s",0," ",0 034B 74007400 034F 6F006E00 0353 73002000 0357 26002000 =1 628 DB "&",0," ",0,"L",0,"i",0,"g",0,"h",0,"t",0,"s",0 035B 4C006900 035F 67006800 0363 74007300 0367 =1 629 String3: ; Configuration Name 0367 2403 =1 630 DB (String4-String3),3 0369 53006900 =1 631 DB "S",0,"i",0,"m",0,"p",0,"l",0,"e",0," ",0,"I",0,"/",0 A51 MACRO ASSEMBLER BAL 21/07/99 16:17:43 PAGE 11 036D 6D007000 0371 6C006500 0375 20004900 0379 2F00 037B 4F002000 =1 632 DB "O",0," ",0,"D",0,"e",0,"v",0,"i",0,"c",0,"e",0 037F 44006500 0383 76006900 0387 63006500 038B =1 633 String4: ; Interface Name 038B 2403 =1 634 DB (EndOfDescriptors-String4),3 038D 46006900 =1 635 DB "F",0,"i",0,"r",0,"s",0,"t",0," ",0,"H",0,"I",0,"D",0 0391 72007300 0395 74002000 0399 48004900 039D 4400 039F 20004500 =1 636 DB " ",0,"E",0,"x",0,"a",0,"m",0,"p",0,"l",0,"e",0 03A3 78006100 03A7 6D007000 03AB 6C006500 03AF =1 637 EndOfDescriptors: 03AF 0000 =1 638 DW 0 ; Backstop for String Descriptors =1 639 =1 640 =1 641 642 $INCLUDE(Main.A51) =1 643 ; This module initializes the microcontroller then executes MAIN forever =1 644 ; =1 645 03B1 =1 646 Reset: 03B1 7581EB =1 647 MOV SP, #235 ; Initialize the Stack 03B4 75927F =1 648 MOV PageReg, #7FH ; Allows MOVX Ri to access EZ-USB memory =1 649 03B7 78D6 =1 650 MOV R0, #Low(USBControl) ; Simulate a disconnect 03B9 E2 =1 651 MOVX A, @R0 03BA 54F3 =1 652 ANL A, #11110011b ; Clear DISCON, DISCOE 03BC F2 =1 653 MOVX @R0, A 03BD 120405 =1 654 CALL Wait100msec ; Give the host time to react 03C0 E2 =1 655 MOVX A, @R0 ; Reconnect with this new identity 03C1 4406 =1 656 ORL A, #00000110b ; Set DISCOE to enable pullup resistor 03C3 F2 =1 657 MOVX @R0, A ; Set RENUM so that 8051 handles USB requests 03C4 E4 =1 658 CLR A 03C5 F520 =1 659 MOV FLAGS, A ; Start in Default state 03C7 =1 660 TurnOffLEDs: 03C7 F548 =1 661 MOV LEDValue, A 03C9 F546 =1 662 MOV Old_Buttons, A 03CB 04 =1 663 INC A ; = 1 03CC F547 =1 664 MOV LEDstrobe, A 03CE =1 665 Initialize4msecCounter: 03CE F542 =1 666 MOV Expired_Time, A 03D0 F549 =1 667 MOV Msec_counter, A 03D2 =1 668 InitializeIOSystem: ; Work around the Dscope monitor I/O needs =1 669 ; Setup Port A as 8-bit OUTPUT port (no alternate functions) =1 670 ; Setup an 8-bit INPUT port using PortB_Bits [7:4] and PortC_Bits[3:0] =1 671 ; Assume a pre-existing configuration (ie Dscope) 03D2 7893 =1 672 MOV R0, #LOW(PortA_Config) ; PageReg = 7F = HIGH(PortA_Config) 03D4 E4 =1 673 CLR A 03D5 F2 =1 674 MOVX @R0, A ; No alternate functions 03D6 799C =1 675 MOV R1, #LOW(PortA_OE) 03D8 F4 =1 676 CPL A ; = 0FFH 03D9 F3 =1 677 MOVX @R1, A ; Enable PortA for Output 03DA 08 =1 678 INC R0 ; Point to PortB_Config 03DB 09 =1 679 INC R1 ; Point to PortB_OE 03DC E2 =1 680 MOVX A, @R0 ; Get current configuration 03DD 540F =1 681 ANL A, #0FH 03DF F2 =1 682 MOVX @R0, A ; No alternate functions on upper nibble 03E0 E3 =1 683 MOVX A, @R1 ; Get current configuration A51 MACRO ASSEMBLER BAL 21/07/99 16:17:43 PAGE 12 03E1 44F0 =1 684 ORL A, #0F0H 03E3 F3 =1 685 MOVX @R1, A ; Enable PortB_Bits[7:4] for Output 03E4 08 =1 686 INC R0 ; Point to PortC_Config 03E5 09 =1 687 INC R1 ; Point to PortC_OE 03E6 E2 =1 688 MOVX A, @R0 ; Get current configuration 03E7 54F0 =1 689 ANL A, #0F0H 03E9 F2 =1 690 MOVX @R0, A ; No alternate functions on lower nibble 03EA E3 =1 691 MOVX A, @R1 ; Get current configuration 03EB 440F =1 692 ORL A, #0FH 03ED F3 =1 693 MOVX @R1, A ; Enable PortC_Bits[3:0] for Output 03EE =1 694 InitializeInterruptSystem: ; First initialize the USB level 03EE E4 =1 695 CLR A 03EF 78AC =1 696 MOV R0, #LOW(IN07IEN) 03F1 F2 =1 697 MOVX @R0, A ; Disable interrupts from IN Endpoints 0-7 03F2 08 =1 698 INC R0 03F3 F2 =1 699 MOVX @R0, A ; Disable interrupts from OUT Endpoints 0-7 03F4 08 =1 700 INC R0 03F5 7403 =1 701 MOV A, #00000011b 03F7 F2 =1 702 MOVX @R0, A ; Enable (Resume, Suspend,) SOF and SUDAV INTs 03F8 08 =1 703 INC R0 03F9 7401 =1 704 MOV A, #00000001b 03FB F2 =1 705 MOVX @R0, A ; Enable Auto Vectoring for USB interrupts =1 706 ; Now enable the main level 03FC 75E801 =1 707 MOV EIE, #00000001b ; Enable INT2 = USB Interrupt (only) 03FF 75A8C0 =1 708 MOV EI, #11000000b ; Enable interrupt subsystem (and Ser1 for dScope) =1 709 =1 710 ; Initialization Complete. =1 711 ; 0402 =1 712 MAIN: 0402 00 =1 713 NOP ; Not much of a main loop for this example 0403 80FD =1 714 JMP MAIN ; All actions are initiated by interrupts =1 715 ; We are a slave, we wait to be told what to do =1 716 0405 =1 717 Wait100msec: 0405 754064 =1 718 MOV Temp, #100 0408 =1 719 Wait1msec: ; A delay loop 0408 90FB50 =1 720 MOV DPTR, #-1200 040B A3 =1 721 More: INC DPTR ; 3 cycles 040C E582 =1 722 MOV A, DPL ; + 2 040E 4583 =1 723 ORL A, DPH ; + 2 0410 70F9 =1 724 JNZ More ; + 3 = 10 cycles x 1200 = 1msec 0412 D540F3 =1 725 DJNZ Temp, Wait1msec 0415 22 =1 726 RET =1 727 0416 =1 728 ProcessOutputReport: ; A Report has just been received =1 729 ; The report is only one byte long in this first example =1 730 ; It contains a new value for the LEDs 0416 907EC0 =1 731 MOV DPTR, #EP0OutBuffer ; Point to the Report 0419 E0 =1 732 MOVX A, @DPTR ; Get the Data 041A F548 =1 733 MOV LEDValue, A ; Update the local variable 041C 22 =1 734 RET =1 735 041D =1 736 CreateInputReport: ; Called from TIMER which detected the need =1 737 ; The report is only one byte long in this first example =1 738 ; It contains a new value for the Buttons 041D 907E80 =1 739 MOV DPTR, #EP1InBuffer ; Point to the buffer 0420 F0 =1 740 MOVX @DPTR, A ; Update the Report 0421 907FB7 =1 741 MOV DPTR, #IN1ByteCount 0424 7401 =1 742 MOV A, #1 0426 F0 =1 743 MOVX @DPTR, A ; Endpoint 1 now 'armed', next IN will get data 0427 22 =1 744 RET =1 745 746 $INCLUDE(Timer.A51) =1 747 ; This module services the real time interrupt =1 748 ; It is also responsible for the "real world" buttons and lights =1 749 ; A51 MACRO ASSEMBLER BAL 21/07/99 16:17:43 PAGE 13 =1 750 ; CHANGE SINCE THE BOOK TEXT WAS FINALIZED: Idle_Time is used by the Operating System =1 751 ; to override the report times defined in the Endpoint Descriptor. A device driver =1 752 ; will modify Idle_Time to change the reporting characteristics of a HID device. =1 753 ; During initialization the OS sets Idle_Time = 0 which turns reporting OFF unless =1 754 ; a change is detected; an application that starts to poll a HID device will appear =1 755 ; to hang. While it is possible to write extra PCHost application code to re-enable =1 756 ; Idle_Time is it simpler to defeat this mechanism by IGNORRING the Idle_Time value. =1 757 ; =1 758 ; Get a Real Time interrupt every One millisecond (using SOF interrupt) =1 759 ; =1 760 ; HID devices work on a 4 millisecond timer =1 761 ; We have one task =1 762 ; a) Strobe the LEDs (only one is ever really on, saves power) 0428 =1 763 ServiceTimerRoutine: 0428 D54926 =1 764 DJNZ Msec_counter, Done ; Only need to check every 4msec 042B 754904 =1 765 MOV Msec_counter, #4 ; Reinitialize =1 766 ; =1 767 ; LED task =1 768 ; Light the next LED in sequence 042E E547 =1 769 MOV A, LEDStrobe ; Get the current enabling pattern 0430 23 =1 770 RL A 0431 F547 =1 771 MOV LEDStrobe, A ; Save for next time 0433 5548 =1 772 ANL A, LEDValue ; Get the LED image 0435 12044C =1 773 CALL WriteLEDs ; Update the real world =1 774 ; =1 775 ; Create an Input Report from the Buttons value =1 776 ; This will be continually overwritten while the PCHost is not polling for data 0438 12043D =1 777 CALL ReadButtons 043B 80E0 =1 778 JMP CreateInputReport ; RETurn via CreateInputReport =1 779 =1 780 ; Talk to the "real world" buttons and lights 043D =1 781 ReadButtons: 043D 907F9A =1 782 MOV DPTR, #PortB_Pins 0440 E0 =1 783 MOVX A, @DPTR 0441 54F0 =1 784 ANL A, #0F0H ; Get upper nibble 0443 F540 =1 785 MOV Temp, A 0445 A3 =1 786 INC DPTR ; Point to PortC_Pins 0446 E0 =1 787 MOVX A, @DPTR 0447 540F =1 788 ANL A, #0FH ; Get lower nibble 0449 4540 =1 789 ORL A, Temp ; Merge both halves together 044B 22 =1 790 RET 044C =1 791 WriteLEDs: 044C F4 =1 792 CPL A ; 0 = LED on 044D 907F96 =1 793 MOV DPTR, #PortA_Out 0450 F0 =1 794 MOVX @DPTR, A 0451 22 =1 795 Done: RET =1 796 797 798 END A51 MACRO ASSEMBLER BAL 21/07/99 16:17:43 PAGE 14 SYMBOL TABLE LISTING ------ ----- ------- N A M E T Y P E V A L U E ATTRIBUTES ACC . . . . . . . . . . . D ADDR 00E0H A B . . . . . . . . . . . . D ADDR 00F0H A BADREQUEST. . . . . . . . C ADDR 01C6H A BUMPDPTR. . . . . . . . . C ADDR 01CCH A BUTTONSANDLIGHTS. . . . . N NUMB ----- CLEARINT2 . . . . . . . . C ADDR 0119H A COMMANDTABLE. . . . . . . C ADDR 01FAH A CONFIGLENGTH. . . . . . . N NUMB 0022H A CONFIGURATIONDESCRIPTOR . C ADDR 02D7H A CONFIGURED. . . . . . . . B ADDR 0020H.0 A COPYRB. . . . . . . . . . C ADDR 01A0H A COPYSD. . . . . . . . . . C ADDR 02B7H A CORRECTSUBROUTINE . . . . C ADDR 01D5H A CREATEINPUTREPORT . . . . C ADDR 041DH A DECONFIGURED. . . . . . . C ADDR 0278H A DEVICEDESCRIPTOR. . . . . C ADDR 02C5H A DEVICE_CLEAR_FEATURE. . . C ADDR 023AH A DEVICE_GET_STATUS . . . . C ADDR 0267H A DEVICE_SET_FEATURE. . . . C ADDR 023AH A DONE. . . . . . . . . . . C ADDR 0451H A DPH . . . . . . . . . . . D ADDR 0083H A DPL . . . . . . . . . . . D ADDR 0082H A DPS . . . . . . . . . . . D ADDR 0086H A EI. . . . . . . . . . . . D ADDR 00A8H A EICON . . . . . . . . . . D ADDR 00D8H A EIE . . . . . . . . . . . D ADDR 00E8H A ENDOFDESCRIPTORS. . . . . C ADDR 03AFH A ENDPOINTDESCRIPTOR. . . . C ADDR 02F2H A ENDPOINT_CLEAR_FEATURE. . C ADDR 023CH A ENDPOINT_GET_STATUS . . . C ADDR 026BH A ENDPOINT_SET_FEATURE. . . C ADDR 023AH A ENDPOINT_SYNC_FRAME . . . C ADDR 023AH A EP0CONTROL. . . . . . . . N NUMB 7FB4H A EP0INBUFFER . . . . . . . N NUMB 7F00H A EP0IN_ISR . . . . . . . . C ADDR 0118H A EP0OUTBUFFER. . . . . . . N NUMB 7EC0H A EP0OUT_ISR. . . . . . . . C ADDR 0118H A EP1INBUFFER . . . . . . . N NUMB 7E80H A EP1IN_ISR . . . . . . . . C ADDR 0118H A EP1OUT_ISR. . . . . . . . C ADDR 0118H A EP2IN_ISR . . . . . . . . C ADDR 0118H A EP2OUT_ISR. . . . . . . . C ADDR 0118H A EP3IN_ISR . . . . . . . . C ADDR 0118H A EP3OUT_ISR. . . . . . . . C ADDR 0118H A EP4IN_ISR . . . . . . . . C ADDR 0118H A EP4OUT_ISR. . . . . . . . C ADDR 0118H A EP5IN_ISR . . . . . . . . C ADDR 0118H A EP5OUT_ISR. . . . . . . . C ADDR 0118H A EP6IN_ISR . . . . . . . . C ADDR 0118H A EP6OUT_ISR. . . . . . . . C ADDR 0118H A EP7IN_ISR . . . . . . . . C ADDR 0118H A EP7OUT_ISR. . . . . . . . C ADDR 0118H A EXIF. . . . . . . . . . . D ADDR 0091H A EXITISR . . . . . . . . . C ADDR 014BH A EXPIRED_TIME. . . . . . . D ADDR 0042H A FIXUPTHENREPLY. . . . . . C ADDR 02B1H A FLAGS . . . . . . . . . . D ADDR 0020H A GET_CLASS_DESCRIPTOR. . . C ADDR 029FH A GET_CONFIGURATION . . . . C ADDR 0264H A GET_DESCRIPTOR. . . . . . C ADDR 027BH A A51 MACRO ASSEMBLER BAL 21/07/99 16:17:43 PAGE 15 GET_IDLE. . . . . . . . . C ADDR 025DH A GET_INTERFACE . . . . . . C ADDR 023AH A GET_PROTOCOL. . . . . . . C ADDR 023AH A GET_REPORT. . . . . . . . C ADDR 0250H A HANDSHAKE . . . . . . . . C ADDR 01ADH A HIDDESCRIPTOR . . . . . . C ADDR 02E9H A I2CCONTROL. . . . . . . . N NUMB 7FA5H A I2CDATA . . . . . . . . . N NUMB 7FA6H A I2CDATABYTE . . . . . . . D ADDR 0046H A I2C_ISR . . . . . . . . . C ADDR 0118H A IDLE_TIME . . . . . . . . D ADDR 0041H A IN07IEN . . . . . . . . . N NUMB 7FACH A IN07IRQ . . . . . . . . . N NUMB 7FA9H A IN0BYTECOUNT. . . . . . . N NUMB 7FB5H A IN1BYTECOUNT. . . . . . . N NUMB 7FB7H A INITIALIZE4MSECCOUNTER. . C ADDR 03CEH A INITIALIZEINTERRUPTSYSTEM C ADDR 03EEH A INITIALIZEIOSYSTEM. . . . C ADDR 03D2H A INT0_ISR. . . . . . . . . C ADDR 0118H A INT1_ISR. . . . . . . . . C ADDR 0118H A INT4_ISR. . . . . . . . . C ADDR 0118H A INT5_ISR. . . . . . . . . C ADDR 0118H A INT6_ISR. . . . . . . . . C ADDR 0118H A INTERFACEDESCRIPTOR . . . C ADDR 02E0H A INTERFACE_CLEAR_FEATURE . C ADDR 023AH A INTERFACE_GET_STATUS. . . C ADDR 026BH A INTERFACE_SET_FEATURE . . C ADDR 023AH A INVALID . . . . . . . . . C ADDR 023AH A ISDESCRIPTOR. . . . . . . B ADDR 0020H.3 A LEDBUFFER . . . . . . . . D ADDR 0046H A LEDSTROBE . . . . . . . . D ADDR 0047H A LEDVALUE. . . . . . . . . D ADDR 0048H A LIGHTVALUES . . . . . . . D ADDR 0046H A LOADSUDPTR. . . . . . . . C ADDR 01B8H A MAIN. . . . . . . . . . . C ADDR 0402H A MONITORSPACE. . . . . . . D ADDR 0021H A MORE. . . . . . . . . . . C ADDR 040BH A MSEC_COUNTER. . . . . . . D ADDR 0049H A NEXTDPTR. . . . . . . . . C ADDR 01CBH A NEXTSTRING. . . . . . . . C ADDR 0291H A NOTB5 . . . . . . . . . . C ADDR 0181H A NOT_USED. . . . . . . . . C ADDR 0118H A OLD_BUTTONS . . . . . . . D ADDR 0046H A OUT07IEN. . . . . . . . . N NUMB 7FADH A OUT07IRQ. . . . . . . . . N NUMB 7FAAH A OUT0BYTECOUNT . . . . . . N NUMB 7FC5H A OVERLAY . . . . . . . . . D ADDR 0046H A PAGEREG . . . . . . . . . D ADDR 0092H A PCON. . . . . . . . . . . D ADDR 0087H A PORTA_CONFIG. . . . . . . N NUMB 7F93H A PORTA_OE. . . . . . . . . N NUMB 7F9CH A PORTA_OUT . . . . . . . . N NUMB 7F96H A PORTA_PINS. . . . . . . . N NUMB 7F99H A PORTB_CONFIG. . . . . . . N NUMB 7F94H A PORTB_OE. . . . . . . . . N NUMB 7F9DH A PORTB_PINS. . . . . . . . N NUMB 7F9AH A PROCESSOUTPUTREPORT . . . C ADDR 0416H A PSW . . . . . . . . . . . D ADDR 00D0H A READBUTTONS . . . . . . . C ADDR 043DH A REPLY . . . . . . . . . . C ADDR 023CH A REPLYBUFFER . . . . . . . D ADDR 0043H A REPORTDESCRIPTOR. . . . . C ADDR 02F9H A REPORTLENGTH. . . . . . . N NUMB 001CH A RESERVED. . . . . . . . . C ADDR 0118H A RESET . . . . . . . . . . C ADDR 03B1H A SENDDATA. . . . . . . . . B ADDR 0020H.2 A A51 MACRO ASSEMBLER BAL 21/07/99 16:17:43 PAGE 16 SENDEP0INBUFFER . . . . . C ADDR 01A9H A SERVICESETUPPACKET. . . . C ADDR 0169H A SERVICETIMERROUTINE . . . C ADDR 0428H A SETEP0CONTROL . . . . . . C ADDR 01B0H A SETUPDAT. . . . . . . . . N NUMB 7FE8H A SET_CLASS_DESCRIPTOR. . . C ADDR 023AH A SET_CONFIGURATION . . . . C ADDR 026EH A SET_DESCRIPTOR. . . . . . C ADDR 023AH A SET_IDLE. . . . . . . . . C ADDR 0257H A SET_INTERFACE . . . . . . C ADDR 023AH A SET_PROTOCOL. . . . . . . C ADDR 023AH A SET_REPORT. . . . . . . . C ADDR 023DH A SKIP. . . . . . . . . . . C ADDR 01D4H A SOF_ISR . . . . . . . . . C ADDR 0158H A SP. . . . . . . . . . . . D ADDR 0081H A STALL . . . . . . . . . . B ADDR 0020H.1 A STARTXFER . . . . . . . . C ADDR 01ACH A STRING0 . . . . . . . . . C ADDR 0315H A STRING1 . . . . . . . . . C ADDR 0319H A STRING2 . . . . . . . . . C ADDR 0345H A STRING3 . . . . . . . . . C ADDR 0367H A STRING4 . . . . . . . . . C ADDR 038BH A SUDAV_ISR . . . . . . . . C ADDR 013CH A SUDPTR. . . . . . . . . . N NUMB 7FD4H A SUSPEND_ISR . . . . . . . C ADDR 0129H A SUTOK_ISR . . . . . . . . C ADDR 0118H A TEMP. . . . . . . . . . . D ADDR 0040H A TIMER0_ISR. . . . . . . . C ADDR 0118H A TIMER1_ISR. . . . . . . . C ADDR 0118H A TIMER2_ISR. . . . . . . . C ADDR 0118H A TURNOFFLEDS . . . . . . . C ADDR 03C7H A UART0_ISR . . . . . . . . C ADDR 0118H A UART1_ISR . . . . . . . . C ADDR 0118H A USBCONTROL. . . . . . . . N NUMB 7FD6H A USBIEN. . . . . . . . . . N NUMB 7FAEH A USBIRQ. . . . . . . . . . N NUMB 7FABH A USBRESET_ISR. . . . . . . C ADDR 0120H A USB_ISR . . . . . . . . . C ADDR 0100H A WAIT100MSEC . . . . . . . C ADDR 0405H A WAIT1MSEC . . . . . . . . C ADDR 0408H A WAIT4D. . . . . . . . . . C ADDR 0247H A WAKEUP_ISR. . . . . . . . C ADDR 0139H A WITHINSAMEPAGE. . . . . . N NUMB 00B7H A WRITELEDS . . . . . . . . C ADDR 044CH A REGISTER BANK(S) USED: 0 ASSEMBLY COMPLETE. 0 WARNING(S), 0 ERROR(S)