; File: PCA_2Buf.A51 Date: 03/06/95 ; ; /* (c) Copyright BLUE EARTH RESEARCH, MANKATO, MN 1991-1995 */ ; /* All rights reserved. */ $ ERRORPRINT PAGELENGTH (60) PAGEWIDTH (110) ; Assembler controls $ XREF TITLE (Dual Port Serial Buffer Routine) $ DATE (03/06/95) NOGEN NOMOD51 ; ----------------------------------------------------------------------------- ; 8051 SERIAL INPUT BUFFER ROUTINE ; Written by Tom Bachmann, Blue Earth Research, Mankato, MN 56001 ; Using initial code developed by Tom Hiniker ; ----------------------------------------------------------------------------- ; This program implements a 256 byte circular buffer for receiving serial ; characters via the '51's on-chip UART. It also implements another serial ; buffer for receiving characters on the second serial port. Software for ; transmitting on both the primary and secondary serial port is also ; provided. The equate table can be changed to relocate the buffer and code ; memory to any user desired memory spaces. ; NOTE: Whenever BASIC writes a character to the on-chip UART, it first tests ; the UART's TI bit to determine if the 1 byte transmit buffer is empty or not. ; If the TI bit is "1", indicating the buffer is now empty, BASIC will then ; clear it and load another character into the buffer. Otherwise, it waits ; until it is a "1". Therefore, if another program should clear the TI bit, ; BASIC will go into a wait forever mode when attempting to write to the serial ; port. ; However, for this serial buffer routine to function properly, the TI bit ; must be cleared or the CPU will continuously service the serial interrupt. ; This will make any other program run very slowly since the CPU will only be ; able to execute one instruction between serial interrupts. This program ; therefore clears the TI bit as part of the serial interrupt routine. As a ; result, the BASIC "PRINT" statement may not be used to output characters to ; the serial port once the serial interrupt has been initialized. ; In order to overcome the lack of a useful TI bit, the serial buffer ; program uses a "Sending1" bit that has a similar function. The Sending1 bit ; is set when a character is written to the serial port and cleared by the ; serial interrupt when the TI bit is set by the UART (indicating that the ; character transmission is complete). ; This program provides a CALL to disable the serial interrupt. The serial ; interrupt should be disabled before the BASIC "PRINT" statement is used to ; write characters to the serial port and when BASIC is expected to receive ; serial characters instead of the serial interrupt routine. This should be ; done before executing an INPUT statement or returning to the command mode. ; ----------------------------------------------------------------------------- ; EXAMPLE BASIC LANGUAGE PROGRAM ; ----------------------------------------------------------------------------- ; The following BASIC program was used to test the double buffer program. ; Note that the following jump table is used in the sample BASIC program: ; Address Function ; ------- --------- ; 7E00H Initialize the Serial Interrupt ; 7E02H Check the buffer for characters ; 7E04H Check the 2nd buffer for characters ; 7E06H Transmit a char on the primary port ; 7E08H Transmit a char on the second port ; 7E0AH Disable serial interrupt ; -------------------------- SAMPLE BASIC PROGRAM ----------------------------- ; REM bump up the Stack Pointer to make room for more internal data memory ; 5 DBY(62)=90 ; REM Wait for a while ; 10 FOR X=1 TO 4000 : NEXT X ; REM Initialize serial interrupt ; 20 CALL 7E00H : CHAR=1DH : CHAR2=1AH ; REM Test primary port buffer ; 30 CALL 7E02H : C=DBY(CHAR) : IF C THEN GOSUB 60 ; REM Test the second port buffer ; 40 CALL 7E04H : C=DBY(CHAR2) : IF C=0 THEN 30 ; ; REM Received a character on the secondary buffer: ; REM Echo the character to the primary port ; 50 DBY(CHAR)=C : CALL 7E06H : GOTO 30 ; ; REM Received a character on the primary buffer: ; REM Primary Port: ; REM Output a CR-LF, echo the char, and then another CR-LF ; REM Secondary Port: ; REM Echo the char ; ; 60 GOSUB 80 : DBY(CHAR)=C : CALL 7E06H : GOSUB 80 ; 70 DBY(CHAR2)=C : CALL 7E08H : RETURN ; ; REM Send CR-LF on primary port ; 80 DBY(CHAR)=0DH : CALL 7E06H ; 90 DBY(CHAR)=0AH : CALL 7E06H : RETURN $ EJECT ; ----------------------------------------------------------------------------- ; ASSEMBLY LANGUAGE PROGRAM ; ----------------------------------------------------------------------------- ; For each serial character received, the Buffer "Head" address pointer is ; bumped and the received character stored into that location. Reading the ; buffer is accomplished by bumping the Buffer "Tail" address pointer and then ; reading that location into "Char" so BASIC can get it using a simple DBY() ; instruction. If the Head & Tail pointers are equal, then the Buffer is ; considered empty. Trying to read an empty Buffer will produce a NULL code ; (0) in Char and will not advance the Tail pointer. A BASIC program can just ; check for a 0 in Char if it does not want to check Head & Tail pointers ; before doing a "ReadBuffer". ; Note that the above is true for BOTH the primary and secondary serial ; ports. The primary port uses the Head, Tail, and Char memory locations, ; while the secondary port uses the Head2, Tail2, and Char2 memory locations. ; ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ; ³ SYMBOL DEFINITIONS ³ ; ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ $ NOLIST ; DON'T SHOW IN LIST FILE $ INCLUDE(REGFX.INC) ; INCLUDE 83C51FB REGISTERS $ LIST ; SHOW THE REST IN THE LIST FILE ; ----------------------------- EQUATE TABLE ---------------------------------- Buffer XDATA 5000H ; Where circular Buffer starts DSEG AT 1AH Char2: DS 1 ; Contains retrieved character Tail2: DS 1 ; Pointer to last character read Head2: DS 1 ; Pointer to last character stuffed Buffer2 XDATA 5100H ; Repeat for 2nd Serial Port Char: DS 1 Tail: DS 1 Head: DS 1 CodeAddr CODE 7E00H ; Locate this program at top of ; write protectable memory space ; --------------------- SECOND SERIAL PORT EQUATE TABLE ----------------------- DSEG AT 4DH BitCounter: DS 1 ; Counter for receiving bits RecvTemp: DS 1 ; Software Receive SBUF TxmCounter: DS 1 ; Counter for sending bits TxmTemp: DS 1 ; Software Transmit SBUF LoHalfBitTime: DS 1 ; Hold the reload values for the HiHalfBitTime: DS 1 ; PCA Serial Port Timing LoFullBitTime: DS 1 ; Hold the reload values for the HiFullBitTime: DS 1 ; PCA Serial Port Timing BSEG AT 0 StartBit: DBIT 1 ; Receive Flags DoneBit: DBIT 1 TxmStart: DBIT 1 ; Transmit Bits InProgress: DBIT 1 Sending1: DBIT 1 ; Primary port "InProgress" bit NegEdge EQU 011H SoftTimer EQU 049H ; NOTE: The serial port Baud Rate can be changed by editing the following ; program variable and then assembling the source file. Baud EQU 96 ; Baud Rate in 00's (9600) FullBitTime EQU 10000/Baud ; 417uS is the bit period HalfBitTime EQU FullBitTime/2 ; for 2400 baud. (12 Mhz) ; Also note that the baud rate reload values are held in internal memory ; locations so that they may be changed at any time by the calling program. $ EJECT ; ------------------------ BEGINNING OF EXECUTABLE CODE ----------------------- CSEG AT CodeAddr AJMP StartSerial ; 7E00H Initialize the Serial Interrupt AJMP ReadBuffer ; 7E02H Check the buffer for characters AJMP ReadBuffer2 ; 7E04H Check the 2nd buffer for characters AJMP WriteChar ; 7E06H Transmit a char on the primary port AJMP WriteChar2 ; 7E08H Transmit a char on the second port ; ------------------------- DISABLE SERIAL INTERRUPT -------------------------- ; May want to load SBUF with 1st character of an output string instead of a ; NULL and let BASIC take care of sending the rest of them. StopSerial: CLR ES ; 7E0AH Disable serial interrupt WriteCR: MOV SBUF,#0DH ; Write to set TI bit RET WriteChar: JB Sending1,$ ; Wait if previous char is not gone. MOV SBUF,Char SETB Sending1 RET ; ---------------------- SERIAL INTERRUPT ROUTINE ----------------------------- SerialInt: JBC TI,TxDInt ; Not a receive interrupt ? PUSH PSW ; Save registers PUSH ACC PUSH DPH PUSH DPL INC Head MOV DPH,#HIGH Buffer ; Page pointer always the same. MOV DPL,Head MOV A,SBUF ; Get serial input character CLR RI ; and reenable interrupt. MOVX @DPTR,A ; Store character in Buffer POP DPL ; Restore registers POP DPH POP ACC POP PSW RETI TxDInt: CLR Sending1 ; Done with primary port character. RETI ; ---------------------- READ CHARACTER FROM BUFFER --------------------------- ReadBuffer: MOV A,Head ; If Head & Tail are the same, XRL A,Tail ; the Buffer is considered empty. JNZ GetChar MOV Char,A ; So return with NULL character RET GetChar: INC Tail MOV DPH,#HIGH Buffer MOV DPL,Tail MOVX A,@DPTR ; Read the Buffer MOV Char,A ; and put it here. RET ; ---------------------- READ CHARACTER FROM BUFFER2 -------------------------- ReadBuffer2: MOV A,Head2 ; If Head & Tail are the same, XRL A,Tail2 ; the Buffer is considered empty. JNZ GetChar2 MOV Char2,A ; So return with NULL character RET GetChar2: INC Tail2 MOV DPH,#HIGH Buffer2 MOV DPL,Tail2 MOVX A,@DPTR ; Read the Buffer MOV Char2,A ; and put it here. RET ; ------------------------INITIALIZE SERIAL INTERRUPT ------------------------- StartSerial: MOV DPTR,#4023H ; Write LJMP code to serial MOV A,#2 ; interrupt vector location. MOVX @DPTR,A INC DPTR MOV A,#HIGH SerialInt MOVX @DPTR,A INC DPTR MOV A,#LOW SerialInt MOVX @DPTR,A MOV DPTR,#4033H ; Stuff "LJMP PCAINT" into MOV A,#2 ; mirrored PCA interrupt MOVX @DPTR,A ; vector at address 4033H. INC DPTR MOV A,#HIGH PCAINT ; Location of PCA MOVX @DPTR,A ; interrupt routine. INC DPTR MOV A,#LOW PCAINT MOVX @DPTR,A ; Now initialize Head and Tail pointers so that the first byte received is ; stored in (and read from) location 0 (the pointers are incremented BEFORE ; the byte is stored or read). TMB 9/23/92 MOV Head,#0FFH ; Initialize Buffer pointers MOV Tail,#0FFH MOV Char,#0 ; Initialize Char to "NULL" MOV Head2,#0FFH ; Initialize Buffer pointers MOV Tail2,#0FFH MOV Char2,#0 ; Initialize Char to "NULL" ; Keep the baud rate reload values in internal memory so that they ; can be changed at any time by the system software. MOV LoHalfBitTime, #LOW HalfBitTime MOV HiHalfBitTime, #HIGH HalfBitTime MOV LoFullBitTime, #LOW FullBitTime MOV HiFullBitTime, #High FullBitTime CLR Sending1 ; Primary port ready for characters ; ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ; ³ INITIALIZE RECEIVE MODE ³ ; ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ CLR StartBit CLR DoneBit MOV RecvTemp,#0 ; ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ; ³ INITIALIZE TRANSMIT MODE ³ ; ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ CLR TxmStart CLR InProgress MOV TxmTemp,#0 $ EJECT ; ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ; ³ INITIALIZE CPU FUNCTIONS ³ ; ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ MOV CL,#0 ; CLEAR PCA TIMER REGISTERS MOV CH,#0 ; ÚÄÄÄÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÄÄ¿ ; CCAPM = ³ -- ³ ECOM ³ CAPP ³ CAPN ³ MAT ³ TOG ³ PWM ³ ECCF ³ ; ÀÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÙ ; Module 3 -> Capture Negative edge w/interrupt ; 0 0 0 1 0 0 0 1 ; Module 4 -> Software Timer for serial port ; 0 1 0 0 1 0 0 1 MOV CCAPM3,#NegEdge ; MOV CCAPM4,#SoftTimer ; NOT YET! MOV CCAPM4,#0 ; ÚÄÄÄÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÄÄ¿ ; CMOD = ³ CIDL ³ WDTE ³ -- ³ -- ³ -- ³ CPS1 ³ CPS0 ³ ECF ³ ; ÀÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÙ ; 0 0 0 0 0 0 0 0 MOV CMOD,#0 ; ÚÄÄÄÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÄÄ¿ ; CCON = ³ CF ³ CR ³ -- ³ CCF4 ³ CCF3 ³ CCF2 ³ CCF1 ³ CCF0 ³ ; ÀÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÙ ; 0 1 0 0 0 0 0 0 MOV CCON,#40H ; ÚÄÄÄÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÄÄ¿ ; IE = ³ EA ³ EC ³ ET2 ³ ES ³ ET1 ³ EX1 ³ ET0 ³ EX0 ³ ; ÀÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÙ ; 1 1 0 1 0 0 0 0 SETB EC SETB ES SETB EA RET $ EJECT ; ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ; ³ SET UP TO TRANSMIT A CHARACTER ³ ; ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ WriteChar2: PUSH PSW JB InProgress,$ ; Make sure no previous chars yet CLR TxmStart ; Clear status flag MOV TxmTemp,Char2 ; Load "SBUF" with data byte MOV TxmCounter,#9 ; 8 data bits + 1 stop bit MOV A,LoFullBitTime ; Setup for the next PCA interrupt ADD A,CL MOV CCAP4L,A MOV A,HiFullBitTime ADDC A,CH MOV CCAP4H,A CLR CCF4 ; Get rid of any old flags MOV CCAPM4,#SoftTimer ; Start the PCA timer compare SETB InProgress POP PSW RET ; End of function call ; ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ; ³ PCA INTERRUPT ³ ; ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ PCAINT: JBC CCF3,ReceiveInt ; Check for receive Interrupt JNB CCF4,NoMore ; Not a valid Interrupt ; ---------------------------- TRANSMIT INTERRUPT ----------------------------- TransmitInt: CLR CCF4 PUSH ACC PUSH PSW JNB InProgress,TxmDone JB TxmStart,SendByte ; See if Start Bit was sent CLR P1.7 ; Otherwise transmit Start bit SETB TxmStart ; Set start bit flag SJMP TxmDone SendByte: DJNZ TxmCounter,TxmNext ; Transmit 8 data bits TxmStop: SETB P1.7 ; Transmit stop bit CLR InProgress ; Transmission Completed! MOV CCAPM4,#0 ; Turn the PCA timer module off SJMP Txm_End TxmNext: MOV A,TxmTemp ; Transmit one bit at a time RRC A ; through the carry bit MOV P1.7,C MOV TxmTemp,A ; Save for next time TxmDone: MOV A,LoFullBitTime ; Setup for next PCA int. ADD A,CCAP4L MOV CCAP4L,A MOV A,HiFullBitTime ADDC A,CCAP4H MOV CCAP4H,A Txm_End: JBC CCF3,ReceiveNow ; Also Check for receive POP PSW POP ACC NoMore: RETI ; ---------------------------- RECEIVE INTERRUPT ------------------------------ ReceiveInt: PUSH ACC PUSH PSW ReceiveNow: MOV A,CCAPM3 ANL A,#7FH CJNE A,#NegEdge,CheckStart MOV A,LoHalfBitTime ; Setup for next PCA int. ADD A,CCAP3L MOV CCAP3L,A MOV A,HiHalfBitTime ADDC A,CCAP3H MOV CCAP3H,A MOV CCAPM3,#SoftTimer POP PSW POP ACC RETI CheckStart: CJNE A,#SoftTimer,Error JB StartBit,DecrBitCtr JB P1.6,Error SETB StartBit MOV BitCounter,#9 SetUpFull: MOV A,LoFullBitTime ; Setup for next PCA int. ADD A,CCAP3L MOV CCAP3L,A MOV A,HiFullBitTime ADDC A,CCAP3H MOV CCAP3H,A POP PSW POP ACC RETI DecrBitCtr: DJNZ BitCounter,RotateBit CheckStop: JNB P1.6,Error CLR StartBit MOV CCAPM3,#NegEdge SETB DoneBit ; Got the character! PUSH DPH ; Save DPTR PUSH DPL INC Head2 ; Increment buffer pointer MOV DPH,#HIGH Buffer2 ; Store received character MOV DPL,Head2 ; in next buffer location. MOV A,RecvTemp MOVX @DPTR,A POP DPL POP DPH ; Restore DPTR POP PSW POP ACC RETI RotateBit: MOV C,P1.6 ; Shift in next data bit. MOV A,RecvTemp RRC A MOV RecvTemp,A SJMP SetUpFull Error: MOV CCAPM3,#NegEdge ; Receive error. CLR StartBit POP PSW POP ACC RETI END ; Following is the HEX file derived from the assembled source ; file. This can be used for directly loading the program via ; MONITOR-51 and almost any terminal program. :107E0000C167C13DC152C110C1CAC2AC75990D2232 :107E10002004FD851D99D2042210991EC0D0C0E017 :107E2000C083C082051F758350851F82E599C29863 :107E3000F0D082D083D0E0D0D032C20432E51F65CA :107E40001E7003F51D22051E758350851E82E0F508 :107E50001D22E51C651B7003F51A22051B75835155 :107E6000851B82E0F51A229040237402F0A3747EF1 :107E7000F0A37419F09040337402F0A3747EF0A361 :107E800074EDF0751FFF751EFF751D00751CFF75E5 :107E90001BFF751A0075513475520075536875547F :107EA00000C204C200C201754E00C202C203755076 :107EB0000075E90075F90075DD1175DE0075D900F2 :107EC00075D840D2AED2ACD2AF22C0D02003FDC212 :107ED00002851A50754F09E55325E9F5EEE554354D :107EE000F9F5FEC2DC75DE49D203D0D02210DB3CAE :107EF00030DC38C2DCC0E0C0D030031C200206C237 :107F000097D2028013D54F09D297C20375DE008045 :107F100013E550139297F550E55325EEF5EEE55431 :107F200035FEF5FE10DB09D0D0D0E032C0E0C0D085 :107F3000E5DD547FB41114E55125EDF5EDE552353D :107F4000FDF5FD75DD49D0D0D0E032B4494A2000BE :107F500019209644D200754D09E55325EDF5EDE560 :107F60005435FDF5FDD0D0D0E032D54D22309628E5 :107F7000C20075DD11D201C083C082051C7583511A :107F8000851C82E54EF0D082D083D0D0D0E032A2E2 :107F900096E54E13F54E80C175DD11C200D0D0D0EC :027FA000E032CD :00000001FF