
; EEPROM connecting lines
_cs   equ p2.0
so    equ p2.1
_wp   equ p2.2   
_hold equ p2.3   
sck   equ p2.4   
si    equ p2.5

; EEPROM Intructions
READ  equ 00000011b
WRITE equ 00000010b
WRDI  equ 00000100b
WREN  equ 00000110b
RDSR  equ 00000101b
WRSR  equ 00000001b


        org 0000h
        ljmp main ; bypassing the interrupt vectors


        org 0030h
main:
        lcall init_ser_port
        lcall init_eeprom

        mov a,#WRSR
        lcall shift_out
        mov a,#0h      ;0h for no protection
        lcall shift_out
        lcall delay_5ms

        lcall init_eeprom_write
        mov a,#'X'
        lcall eeprom_write_byte

        nop
        nop ;some delay

        lcall eeprom_read_byte
        sjmp $




; Establish default values for EEPROM bus lines
init_eeprom:
        setb _cs     ;_cs default as HIGH : to NOT select chip when not needed
        setb _wp     ;_wp default as HIGH : to allow writes
        clr _hold    ;_hold default as LOW : to select device always , unless overridden
        setb sck     ;sck default as HIGH : as idle condition
        setb so      ;so default as HIGH : as idle condition
        setb si      ;si default as HIGH : as idle condition
        ret
        



; WRITE Specific init routine
init_eeprom_write:
        clr _cs     ;setting _cs to low first
        mov a,#WREN
        lcall shift_out
        setb _cs  ;bringing up _cs to HIGH again to set write latch
        ret

eeprom_write_byte:
        clr _cs   ;selecting chip before writing
        push acc  ;saving byte to write to stack for the moment
        mov a,#WRITE
        lcall shift_out
        ;sending address to write as 0000h for writing
        mov a,#0h
        lcall shift_out
        lcall shift_out

        pop acc   ;recovering byte to write from stack
        lcall shift_out
        setb _cs  ;de-asserting _cs after writing is over
        ret

eeprom_read_byte:
        clr _cs   ;asserting _cs just before reading
        mov a,#READ
        lcall shift_out

        ;Sending address to read from first, 0000h
        mov a,#0h
        lcall shift_out
        lcall shift_out

        ;read the data byte now
        lcall shift_in
        setb _cs   ;de-asserting _cs after reading is over
        ret
        

shift_out:
        ;data to shift out is in A, and we have to shift it out, MSB first via si
        mov r0,#8
        clr C
_back:        
        rlc A
        mov si,C
        clr sck  ;lowering clock from idle level(HIGH)
        nop      ;some delay
        setb sck ;raising clock to latch bit
        nop      ;again some delay to allow EEPROM to digest what we just sent
        djnz r0,_back ;repeat for all bits in A
        ret
        
shift_in:
        ;data would be shifted in via so line
        mov r0,#8
        clr C
        mov a,#00h
        setb so
_back1:
        clr sck
        nop
        setb sck ;this will cause EEPROM to vomit out the bit onto so
        nop
        nop
        mov C,so
        rlc A    ;this rotation would pack the bits starting with MSB and then proceed to LSB
        nop      ;some delay
        djnz r0,_back1
        lcall send_one_char
        ret


init_ser_port:
        ;Initializing the serial baud rate generator
        mov ie,#10010100b      ;enabling the serial port interrupt and int1
        setb it1              ;to set interrupt 1 as edge triggered
        mov tmod, #20h        ;timer 1, mode 2(auto reload mode)
        mov th1,#-3           ;9600 baud rate 
        mov scon,#50h         ;8-bit, 1 stop bit, ren enabled 
        setb tr1              ;start timer 1
        ret


send_one_char:
        mov sbuf,a
        jnb ti,$
        clr ti
        ret

recv_one_char:
        jnb ri,$
        mov a,sbuf
        clr ri
        ret

 delay_5ms: 
         mov r1, #250   ; write cycle time 
 dly5ms1: 
         lcall dly20us       ; ~250 * 20us = 5msec 
         djnz r1, dly5ms1  
	     ret 


dly20us:
        mov r2, #38     ; 0.5 usec 
dly20:  
        djnz r2, dly20  ; 0.5 usec * 38 = 19 usecs  
	    ret                 ; 0.5 usec 

        

end


