	PAGE	10000
;*******************************************************************************
; PROGRAM DESCRIPTION:
; Many system are implemented by IIC communication theory, it is came from
; Philips and use two wires, one is clock line and another is data line.
;-------------------------------------------------------------------------------
; MICROCONTROLLER : GMS87C1202 (2K ROM, 20 PIN DIP)
; OPER. FREQUENCY : 4MHz
; SERIAL EEPROM   : X24C02 (2KBIT, 8 PIN DIP)
;-------------------------------------------------------------------------------
; programmed by Jongpil Shin (Hynix) on 1999.08.20     Version 1.00
;*******************************************************************************
;
;                 TYPICAL APPLICATION CIRCUIT
;
;             +-------------------+
;             |        (__)       |          +5V
;            1|RA4/AN4     AN3/RA3|20        |
;             |                   |      +---+-----+
;            2|RA5/AN5     AN2/RA2|19    |   |     |
;             |                   |      |   |     |
;            3|RA6/AN6  G  AN1/RA1|18    /   /22K |
;             |         M         |      /   /     | 7+--------+
;            4|RA7/AN7  S  EC0/RA0|17    |   |     +--|VDD   WP|--+
;             |         8         |      |   |       6|        |  |
;       +5V  5|VDD      7      RC1|16-------+--------|SCL   A2|--+
;             |         C         |          |       5|        |  |
;            6|RB0/AN0  1      RC0|15--------+--------|SDA   A1|--+
;             |         2         |                   |        |  |
;            7|RB1/BUZ  0      VSS|14  GND            |      A0|--+
;             |         2         |                   |        |  |
;            8|RB2/INT0     /RESET|13  /Reset         |     VSS|--+
;             |                   |                   +--------+  |
;            9|RB3/INT1       XOUT|12  X-tal Out       24C02      GND
;             |                   |                    EEPROM
;           10|RB4/PWM/COMP    XIN|11  X-tal In  
;             |                   |              
;             +-------------------+
;                  GMS87C1202
;
;*****************************************************************
; * Included Subroutines
; IIC_Rx    : Receive one byte through the IIC bus
; IIC_Tx    : Transmmit one byte through the IIC bus
; IIC_start : Goes to "start condition"
; IIC_stop  : Goes to "stop condition"
;*****************************************************************
; * Using I/O pins
; PIO_SDA   : IIC bus serial data line port, the RC0 pin is used
; PO_SCL	  : IIC bus serial clock line port, the RC1 pin is used	
;*****************************************************************
; * Used RAM
;   - none
;*****************************************************************
;
RC		EQU	0C4H		
RCIO		EQU	0C5H

INPUT_MODE	EQU	0000_0010B	        ; make SDA pin as an input port to read acknowledge
OUTPUT_MODE	EQU	0000_0011B	        ; make SDA pin as an output port to write bit and acknowledge
PO_SCL		EQU	1,RC
PIO_SDA		EQU	0,RC

;************** VECTOR AREA *****************
;
	ORG	0FFFEH
	DW	RESET             		;Reset Vector

	ORG	0F800H

RESET:	LDX	#07FH			        ;Initialize SP = #7FH
	TXSP				
	LDM	RC,#0000_0011B
	LDM	RCIO,#0000_0011B
        JMP     START

;*******************************************************************************
;  Write one byte data into the EEPROM
;  - Write one byte data (Accumulator) at address X of EEPROM
;*******************************************************************************
;  Input parameter
;    - Accumulator : write data
;    - X register  : write address
;  Output parameter
;    - None
;  Scrached data
;    - Y register  : shift bit counter
;-------------------------------------------------------------------------------
;  Thie write cycle time is the time(max10ms) from a valid stop condition of a
;  write sequence to the end of the internal erase/program cycle, During the write
;  cycle, the EEPROM bus interface circuits are disabled, SDA is allowed to
;  remain high, and the device dows not respond to its slave address.
;*******************************************************************************

write_byte: 
	PUSH	A
	CALL	IIC_start
	LDA	#0A0H			        ; set to be "byte write condition"
	CALL	IIC_Tx			        ; tx. one byte via IIC bus
	XAX				        ; set word address (X -> A)
	CALL	IIC_Tx			        ; tx. one byte(address) to slave
	POP	A			        ; set one byte data to be wrote
	CALL	IIC_Tx			        ; tx. one byte(data) to slave
	CALL	IIC_stop			; make "stop condition"
	RET
;	
;*******************************************************************************
;  Read one byte data from the EEPROM
;  - One byte data is read from EEPROM address X of EEPROM
;*******************************************************************************
;  Input parameter
;    - X register  : read address
;  Output parameter
;    - Accumulator : one byte data
;  Scrached data
;    - Y register  : shift bit counter
;*******************************************************************************
ReadFromEEPROM:	
read_byte: 
	CALL	IIC_start
	LDA	#0A0H			        ; set to be "byte write condition"
	CALL	IIC_Tx			        ; transmit one byte (slave address) via IIC bus
	XAX				        ; set word address (X -> A)
	CALL	IIC_Tx			        ; transmit one byte(word address) to slave
	CALL	IIC_start			; set to be start condition
	LDA	#0A1H			        ; set to be "byte write condition"
	CALL	IIC_Tx			        ; transmit one byte (slave address) via IIC bus
	NOP
	CALL	IIC_Rx			        ; receive one byte(data) to slave
	CALL	IIC_stop			; make "stop condition"
	RET
;
;----------------------------------------------------------
; TRANSMIT ONE BYTE DATA VIA IIC BUS	
;----------------------------------------------------------
;  Entry        : Accumulator (to be wrote transmit data)
;  Output       : Carry (0=ok, 1=No ack, maybe error)
;  Scratch data : Y register is used shift counter and will be decremented
;----------------------------------------------------------
IIC_Tx:	LDM	RCIO,#OUTPUT_MODE 		; set SDA as an output mode 

	LDY	#6			        ; prepare shift counter seven clock counter
iic_loop:	                                ; Transmit seven clocks 
	ROL	A			        ; get one bit to be send
	STC	PIO_SDA			        ; transmit one bit through the data line
	NOP
	NOP
	NOP
        SET1	PO_SCL			        ; make clock rising edge
        NOP
        NOP
        CLR1	PO_SCL			        ; make clock falling edge
        DEC	Y			        ; eight bits done ?
        BPL	iic_loop		        ; no -> coutinue tx. the bit
                                                ; Transmit eighth clock 
        ; - Ack. form slave is output when eighth clock is fall, 
        ; so SDA pin have to be input mode as below 
        NOP
        ROL	A
        STC	PIO_SDA
        BCC	iic_l3			        ; LSB is 0 ?
        SET1	PO_SCL			        ; No, LSB is "1", SDA have to be input mode before fall...
        LDM	RCIO,#INPUT_MODE		; ... of eighth clock to prevent skew with Ack. from slave
	CLR1	PO_SCL
        BRA	check_ack
iic_l3:	SET1	PO_SCL			        ; Yes, LSB is "0", there is no ban skew condition between SDA and Ack.
        NOP				        ; SDA goes to be input mode normally after fall of eighth clock
        NOP
        NOP
        NOP
        NOP
	CLR1	PO_SCL
        LDM	RCIO,#INPUT_MODE	        ; make SDA port as an input port to read ack. signal
                                                ; all eight bits data is transmitted,
	                                        ; this time acknowledge bit have to be checked
check_ack:                                      ; Transmit ninth clock
	CALL	delay1
	SET1	PO_SCL			        ; Ninth clock cycle output to read Ack.
	LDCB	PIO_SDA			        ; Read Ack. If Carry is 1, then error
	CLR1	PO_SCL			        ; for next procedure
	SET1	PIO_SDA			        ; make to be initial state...
	RET
        	        
;----------------------------------------------------------
; RECEIVE ONE BYTE DATA VIA IIC BUS	
;----------------------------------------------------------
;  Entry        : None
;  Output       : Accumulator (Received one byte data)
;  Scratch data : Y will be decremented
;----------------------------------------------------------
IIC_Rx:	LDY	#7			        ; prepare shift counter
iic_l2:	NOP
	NOP
	SET1	PO_SCL                          ; request to slave (EEPROM) output one bit
	LDC	PIO_SDA			        ; Read one bit and store to Carry
	ROL	A
	CLR1	PO_SCL			        ; end read one bit
        DEC	Y			        ; all eight bits done ?
        BPL	iic_l2			        ; no -> read rx. data coutinuously
          
        ; It should be noted that the ninth clock cycle of the read operation is not a "don't care".
	; To terminate a read operation, the master must either issue a stop condition during the
	; ninth cycle or hold SDA HIGH during the ninth clock cycle and then issue a stop condition.
	LDM	RCIO,#OUTPUT_MODE		; make SDA port as an input port to read ack. signal
	SET1	PIO_SDA			        ; hold SDA is "high" during ninth clock
	NOP
	SET1	PO_SCL			        ; generate ninth clock
	NOP				        ; delay
	CLR1	PO_SCL			        ; end session
	RET
;----------------------------------------------------------
; Make EEPROM to be "START CONDITION"   
; - All commands are preceded by the start condition which
;   is a HIGH  to LOW transition of SDA when SCL is HIGH.
;----------------------------------------------------------
IIC_start:
	LDM	RCIO,#OUTPUT_MODE 		; set SDA as an output mode 
	SET1	PIO_SDA			        ; initialize SDA to be normal state
	SET1	PO_SCL			        ; initialize SDA to be normal state			
	CALL	delay4
	CLR1	PIO_SDA			        ; make start condition throught execution below line
	NOP
	NOP
	CLR1	PO_SCL
	RET	
;----------------------------------------------------------
; Make EEPROM to be "STOP CONDITION"   
; - All communication must be terminated by a sotp condition,
;   which is a LOW to High transition of SDA when SCL is HIGH.
;----------------------------------------------------------
IIC_stop:
        LDM	RCIO,#OUTPUT_MODE 		; set SDA as an output mode 
	CLR1	PIO_SDA
	NOP
	NOP
	SET1	PO_SCL
	NOP
	NOP
	SET1	PIO_SDA
	RET	
	
;----------------------------------------------------------
; Delay routine
; - delay1 :  13 cycles long,  13*0.5us =  6.5us
; - delay2 :  26 cycles long,  26*0.5us = 13.0us
; - delay4 :  52 cycles long,  52*0.5us = 26.0us
; - delay4 : 104 cycles long, 104*0.5us = 52.0us
;----------------------------------------------------------
	
delay4:	call	delay3
delay3:	call	delay2
delay2:	call 	delay1
delay1:	RET				        ; execution time needs 5 cycle

delay10ms:                                      ; approxmately 10ms
	LDX	#14 
dx1:    LDY	#0EDH
dy1:	DEC	Y
	BNE	dy1
	DEC	X
	BNE	dx1
	NOP
	RET

;Test program to read and wirite random
START:  LDX     #3                              ; set r/w loc. = 2
        LDA     #85                             ; write 85
        CALL    write_byte                      ; write 85 to EEPROM
        CALL	delay10ms			; delay 10ms for write processing
        LDX     #3
        CALL    read_byte
        CMP     #85
        BEQ     CORRECT
WRONG:            
        JMP     WRONG
CORRECT:          
        JMP     CORRECT          

	END		
