;******************************
;* Program For Serial EEPROM  *
;* 93X56 8-bit Data Interface *
;* Files Name  : 93x56-08.ASM *
;* CPU Control : AT89C2051    *
;* Assembler   : SXA51        *
;******************************
 
            CS_EEPROM   EQU     P3.2        ; Chip select EEPROM (INT0)
            SK_EEPROM   EQU     P1.4        ; Serial clock EEPROM
            DI_EEPROM   EQU     P1.5        ; Data in EEPROM (INT1)
            DO_EEPROM   EQU     ACC.5       ; Data out from EEPROM
            PORT_EEP    EQU     P1          ; Port Data I/O EEPROM
            ;
            ADDRESS     EQU     20H
            DATA        EQU     21H
            COUNT       EQU     22H
            LINE        EQU     23H

            ORG     0000H
MAIN:       MOV     SP,#128-32          ; Initial Stack 32 Byte
INIT_SER:   MOV     A,#0FDH             ; Set baud rate 9600
            MOV     TH1,A
            MOV     TL1,A
            MOV     TMOD,#00100000B     ; Timer1 Mode 1
            CLR     ES                  ; Disable serial interupt
            CLR     ET1                 ; Disable timer1 interupt
            SETB    TR1                 ; Set timer1 control
            MOV     SCON,#01010000B     ; Serial mode 1
            ;
            LCALL   PRINT_SER
            DB      0CH,'Hardware  CP-2051 V2.0',0DH,0AH
            DB      'ETT CO.,LTD',0DH,0AH
            DB      'Test Serial eeprom 93x56 (256x8) '
            DB      0DH,0AH,0DH,0AH,00H
            ;
            LCALL   PRINT_SER
            DB      'Write 01H to Address 00H',00H
            MOV     DPL,#01H            ; Data To Write eeprom
            MOV     A,#00H              ; Address EEprom
            LCALL   WRITE_WORD          ; Write Data to eeprom
            LCALL   PRINT_SER
            DB      0DH,0AH
            DB      'Read eeprom Address 00H = ',00H
            MOV     A,#00H              ; Address to Read eeprom
            LCALL   READ_WORD           ; Read Data From eeprom
            MOV     A,DPL               ; Data
            LCALL   TX_2ASC
            ;
            LCALL   PRINT_SER
            DB      0DH,0AH,0DH,0AH
            DB      'Write 23H to Address FFH',00H
            MOV     DPL,#23H            ; Data To Write eeprom
            MOV     A,#0FFH             ; Address EEprom
            LCALL   WRITE_WORD          ; Write Data to eeprom
            LCALL   PRINT_SER
            DB      0DH,0AH
            DB      'Read eeprom Address FFH = ',00H
            MOV     A,#0FFH             ; Address to Read eeprom
            LCALL   READ_WORD           ; Read Data From eeprom
            MOV     A,DPL
            LCALL   TX_2ASC
            ;
            SJMP    $

;***********************************
;* Subroutine for EEPROM 93AA56    *
;* 8-Bits Organization (256x8)     *
;* Reference to Microchips Data Ic *
;* EWEN  : Erase/Write Enable      *
;* EWDS  : Erase/Write Disable     *
;* WRITE : Write Data 8-Bit 1-Byte *
;* ERASE : Erase Data 8-Bit 1-Byte *
;* READ_WORD  : Read 8-Bit 1-Byte  *
;* WRITE_WORD : Write 8-Bit 1-Byte *
;***********************************

;**********************
;*    EWEN Command    *
;* Erase/Write Enable *
;**********************
;
EWEN:       CLR     DI_EEPROM
            SETB    CS_EEPROM           ; Erase/Write Enable command
            SETB    DI_EEPROM
            LCALL   CLOCK               ; 1
            CLR     DI_EEPROM
            LCALL   CLOCK               ; 0
            LCALL   CLOCK               ; 0
            SETB    DI_EEPROM
            LCALL   CLOCK               ; 1
            LCALL   CLOCK               ; 1
            CLR     DI_EEPROM
            LCALL   CLOCK               ; X(0)
            LCALL   CLOCK               ; X(0)
            LCALL   CLOCK               ; X(0)
            LCALL   CLOCK               ; X(0)
            LCALL   CLOCK               ; X(0)
            LCALL   CLOCK               ; X(0)
            LCALL   CLOCK               ; X(0)
            CLR     CS_EEPROM           ; Standby
            RET

;***********************
;*     EWDS Command    *
;* Erase/Write Disable *
;***********************
;
EWDS:       CLR     DI_EEPROM
            SETB    CS_EEPROM           ; Erase/Write Disable command
            SETB    DI_EEPROM               
            LCALL   CLOCK               ; 1
            CLR     DI_EEPROM
            LCALL   CLOCK               ; 0
            LCALL   CLOCK               ; 0
            LCALL   CLOCK               ; 0
            LCALL   CLOCK               ; 0
            LCALL   CLOCK               ; X(0)
            LCALL   CLOCK               ; X(0)
            LCALL   CLOCK               ; X(0)
            LCALL   CLOCK               ; X(0)
            LCALL   CLOCK               ; X(0)
            LCALL   CLOCK               ; X(0)
            LCALL   CLOCK               ; X(0)
            CLR     CS_EEPROM
            RET

;*********************************
;* WRITE DATA TO EEPROM (93AA56) *
;* Input    : ACC  = Address     *
;*          : DPL  = Data(8-Bit) *
;*********************************
;
WRITE:      CLR     DI_EEPROM
            SETB    CS_EEPROM           ; Write command
            SETB    DI_EEPROM
            LCALL   CLOCK               ; 1
            CLR     DI_EEPROM
            LCALL   CLOCK               ; 0
            SETB    DI_EEPROM
            LCALL   CLOCK               ; 1
            LCALL   CLOCK               ; X(1)
            MOV     R2,#8
            CLR     CY
WREEP1:     RLC     A                   ; Write  address 8 bit
            MOV     DI_EEPROM,C
            LCALL   CLOCK
            DJNZ    R2,WREEP1           ; Repeat write address
            ;
            MOV     R2,#8               ; Write data 8 bit in DPL
            MOV     A,DPL
WREEP2:     RLC     A                   ; Write data D7..D0
            MOV     DI_EEPROM,C
            LCALL   CLOCK
            DJNZ    R2,WREEP2
            ;
            CLR     DI_EEPROM
            CLR     CS_EEPROM
            LCALL   CLOCK               ; TCSL
            SETB    CS_EEPROM
WR_STAT:    LCALL   CLOCK               ; wait ready state
            SETB    DI_EEPROM
            MOV     A,PORT_EEP
            MOV     C,DO_EEPROM
            JNC     WR_STAT             ; Repeat if Busy
            CLR     CS_EEPROM           ; OK ready So Standby
            RET

;**************************
;*        Erase byte      *
;* Input : ACC = Address  *
;**************************
;
ERASE:      CLR     DI_EEPROM
            SETB    CS_EEPROM           ; Erase command
            SETB    DI_EEPROM               
            LCALL   CLOCK               ; 1
            LCALL   CLOCK               ; 1
            LCALL   CLOCK               ; 1
            LCALL   CLOCK               ; X(1)
            MOV     R2,#8
            CLR     CY
RAS1:       RLC     A                   ; Write Address 8 bit
            MOV     DI_EEPROM,C
            LCALL   CLOCK
            DJNZ    R2,RAS1
            CLR     DI_EEPROM
            CLR     CS_EEPROM
            LCALL   CLOCK               ; TCLS
            SETB    CS_EEPROM
BUSY:       LCALL   CLOCK
            SETB    DI_EEPROM
            MOV     A,PORT_EEP
            MOV     C,DO_EEPROM
            JNC     BUSY                ; Loop if Busy
            CLR     CS_EEPROM           ; OK Ready So Standby
            RET

;*********************************
;* READ DATA FROM EEPROM(93AA56) *
;* Input    : ACC = Address      *
;* Output   : DPL = Data (8-Bit) *
;* Reg.     : ACC,R2,DPTR        *
;* Read DPH = 1st &  DPL = 2nd   *
;*********************************
;
READ_WORD:  CLR     DI_EEPROM
            SETB    CS_EEPROM           ; Read Command
            SETB    DI_EEPROM               
            LCALL   CLOCK               ; 1
            LCALL   CLOCK               ; 1
            CLR     DI_EEPROM
            LCALL   CLOCK               ; 0
            LCALL   CLOCK               ; X(0)
            MOV     R2,#8
            CLR     CY
RDEEP1:     RLC     A                   ; Write address 8 bit
            MOV     DI_EEPROM,C
            LCALL   CLOCK
            DJNZ    R2,RDEEP1           ; Repeat write address
            CLR     DI_EEPROM            
            MOV     R1,#0
            MOV     R2,#8
RDEEP2:     LCALL   CLOCK               ; Read data D0..D7
            SETB    DI_EEPROM
            MOV     A,PORT_EEP
            MOV     C,DO_EEPROM         ; Read data out bit
            MOV     A,R1
            RLC     A
            MOV     R1,A
            DJNZ    R2,RDEEP2
            MOV     DPL,R1              ; 1st Byte
            MOV     DPH,#0              ; Dont Care 2nd Byte
            CLR     CS_EEPROM
            RET

;***************************
;* Write 'WORD' To EEPROM  *
;* Input : DPL  = Data     *
;*       : ACC  = Address  *
;* Reg.  : ACC,R2,DPTR     *
;***************************
;
WRITE_WORD: PUSH    ACC
            LCALL   EWEN                ; Erase/Write Enable
            POP     ACC                 ; Get address
            PUSH    ACC                 ; Save address
            LCALL   ERASE               ; Erase before write
            POP     ACC                 ; Get address
            LCALL   WRITE               ; Write
            LCALL   EWDS                ; Erase/Write Disable
            RET

;******************
;*  Serial clock  *
;******************
;
CLOCK:      SETB    SK_EEPROM           ; SK = hi
            NOP
            NOP
            NOP
            NOP
            CLR     SK_EEPROM           ; SK = low
            NOP
            NOP
            NOP
            NOP
            RET

;************************************
;*  Print Data data to Serial Port  *
;*  to display buffer.              *
;*  Usage    : LCALL PRINT_SER      *
;*           : DB   'xxxx',00       *
;*  Register : ACC                  *
;*  Note     : last byte must be 00 *
;************************************
;
PRINT_SER:  POP     DPH
            POP     DPL
PRINT1:     CLR     A
            MOVC    A,@A+DPTR
            CJNE    A,#00H,PRINT2
            SJMP    PRINT3
PRINT2:     LCALL   TX_BYTE
            INC     DPTR
            SJMP    PRINT1
PRINT3:     PUSH    DPL
            PUSH    DPH
            RET

;****************************
;* Receive Data From RS-232 *
;* Input   :  Serial Port   *
;* Output  :  ACC           *
;****************************
;
RX_BYTE:    PUSH   IE
            JNB    RI,$             ; Wait data
            CLR    RI
            MOV    A,SBUF
            POP    IE
            RET

;*************************
;* Send 1-Byte to RS-232 *
;* Input   : ACC         *
;* Output  : Serial port *
;*************************
;
TX_BYTE:    PUSH   IE
            CLR    TI
            MOV    SBUF,A
            JNB    TI,$
            CLR    TI
            POP    IE
            RET

;******************************
;*    Send 2 byte of ASCII    *
;*  Input : ACC (HEX)         *
;*  Example : A = A3H         *
;*          : send 41H,33H    *
;******************************
;
TX_2ASC:    LCALL   HEX_2ASC
            LCALL   TX_BYTE
            MOV     A,B
            LCALL   TX_BYTE
            RET

;******************************
;*   Convert HEX to ASCII     *
;* Input    :  A              *
;* Output   :  A (high-byte)  *
;*          :  B (low-byte)   *
;******************************
;
HEX_2ASC:   PUSH    ACC
            LCALL   HEX_TO_ASC
            MOV     B,A              ; B = Lo byte
            POP     ACC
            SWAP    A
            LCALL   HEX_TO_ASC
            RET

;********************************
;*  Convert hex (0-F) to ASCII  *
;*  Input   : ACC (HEX code)    *
;*  Output  : ACC (ASCII code)  *
;********************************
;
HEX_TO_ASC: PUSH    PSW
            CLR     CY
            ANL     A,#00001111B
            CJNE    A,#09H,HTOA1
            SETB    CY
HTOA1:      JNB     CY,HTOA2       ;> 0AH
            ORL     A,#30H         ;< 0AH
            SJMP    END_HTOA
HTOA2:      SUBB    A,#09H         ;> 0AH
            ORL     A,#40H
END_HTOA:   POP     PSW
            RET

            END

            ;***************************
            ;* PROGRAM  MODE 2 SERVICE *
            ;*  WRITE DATA TO EEPROM   *
            ;*   START PROGRAM HERE    *
            ;***************************
            ;
TEST_93C56: MOV     P1,#0           ; Initial Port
            MOV     COUNT,#13       ; Test Write
            MOV     DATA,#41H
            MOV     ADDRESS,#00H
LOOP1:      MOV     A,ADDRESS
            MOV     DPH,DATA        ; 1st Byte
            INC     DATA
            MOV     DPL,DATA        ; 2nd Byte
            LCALL   WRITE_WORD
            INC     ADDRESS
            INC     DATA
            DJNZ    COUNT,LOOP1
            ;
            MOV     COUNT,#13
            MOV     DATA,#61H
LOOP2:      MOV     A,ADDRESS
            MOV     DPH,DATA        ; 1st Byte
            INC     DATA
            MOV     DPL,DATA        ; 2nd Byte
            LCALL   WRITE_WORD
            INC     ADDRESS
            INC     DATA
            DJNZ    COUNT,LOOP2
            ;
            MOV     COUNT,#5
            MOV     DATA,#30H
LOOP3:      MOV     A,ADDRESS
            MOV     DPH,DATA        ; 1st Byte
            INC     DATA
            MOV     DPL,DATA        ; 2nd Byte
            LCALL   WRITE_WORD
            INC     ADDRESS
            INC     DATA
            DJNZ    COUNT,LOOP3
            ;
            MOV     ADDRESS,#0      ; Test Read EEPROM
            MOV     DATA,#0
            MOV     LINE,#16        ; 16-Line
NEW_LINE:   MOV     A,#0DH          ; Display Data & Address
            LCALL   TX_BYTE
            MOV     A,#0AH
            LCALL   TX_BYTE
            MOV     A,DATA          ; 00
            LCALL   TX_2ASC         ; Display Address
            MOV     A,#20H
            LCALL   TX_BYTE
            MOV     A,#':'
            LCALL   TX_BYTE
            MOV     A,#20H
            LCALL   TX_BYTE
            MOV     COUNT,#8
LOOP4:      MOV     A,ADDRESS
            LCALL   READ
            MOV     A,DPH
            LCALL   TX_2ASC
            MOV     A,DPL
            LCALL   TX_2ASC
            INC     ADDRESS
            DJNZ    COUNT,LOOP4
            MOV     A,#20H
            LCALL   TX_BYTE
            MOV     A,#20H
            LCALL   TX_BYTE
            MOV     A,#':'
            LCALL   TX_BYTE
            MOV     A,#20H
            LCALL   TX_BYTE
            ;
            MOV     A,#8
            SUBB    A,ADDRESS
            MOV     ADDRESS,A
            MOV     COUNT,#8
LOOP5:      MOV     A,ADDRESS
            LCALL   READ
            MOV     A,DPH
            LCALL   TX_BYTE
            MOV     A,DPL
            LCALL   TX_BYTE
            INC     ADDRESS
            DJNZ    COUNT,LOOP5
            ;
            MOV     A,#8
            ADD     A,DATA
            MOV     DATA,A
            DJNZ    LINE,JMP_NEW
            SJMP    $

JMP_NEW:    LJMP    NEW_LINE

