CRYSTAL COMMUNICATION SDN BHD (306943 T)

Homepage

                   

About us

 

Content:

Manufacturing

- Telephone

- Smart card

- GPS

- CD

 

R&D

- Smart card

- PCB prototype

- Micro controller

- Electronics Design

 

International

- Sales office

 

Software

Caller ID

800MHz Cellular

1.2GHz Cellular

 

Specification

- Telephone

- CD

- Smart card

- GPS

 

Contact us:

[email protected]

 

 

CID - Caller line identification


************************************************************************
* Project : Calling Line Identification Done by: HASSAN E *
* Microcontroller: MC68HC05F6 Date :01-01-02 *
* Version No : 1.0 Release : 1.0 *
* This Program is the property of Crystal Communication with its regd. office, *
* Crystal Communication *
* Lot 8 *
* Putra World Trade Centre *
*41 Jln Tun Ismail*
* 50480, Kuala Lumpur, *
* MALAYSIA *
* and is protected by Copyright Protection Act of Malaysia. *
* It shall not be Copied or Modified or Circulated or Reproduced or *
* Duplicated by whatsoever means, Optical or Magnetic or Hardcopy or *
* Electrical or Electro-mechanical or Photographic without the prior *
* written permission and approval of Crystal Communication. *
************************************************************************
* REGISTER EQUATES

PORTA EQU $00 ; PORTA DATA REGISTER
*====================
COL2 EQU $2
COL1 EQU $3
ROW2 EQU $4
ROW1 EQU $5
*====================

PORTB EQU $01 ; PORTB DATA REGISTER
PORTC EQU $02 ; PORTC DATA REGISTER
*====================
LCD_ON EQU $6 ; LCD POWER ON.
BUZZ_DRIVE EQU $7 ; BUZZER DRIVE PIN.
*====================

PORTD EQU $03 ; PORTD DATA REGISTER
*===================
REG_SEL EQU $0 ; REGISTER SELECT PIN OF THE LCD DISPLAY.
RD_WR EQU $1 ; READ/WRITE SIGNAL FOR LCD DISPLAY.
LCD_ENABLE EQU $2 ; ENABLE SIGNAL CONTROL PIN FOR LCD.
RDO EQU $3 ; RING DETECT INPUT FROM THE CLID CHIP.
CLID_CHIP_PWR EQU $4 ; POWER INPUT FOR THE CLID CHIP 145447.
BATT_LOW EQU $5 ; INPUT SIGNAL FOR LOW BATTERY INDICATION.
RAW_DATA EQU $6 ; RAW DATA INPUT FROM THE CLID CHIP
COOK_DATA EQU $7 ; COOK DATA INPUT FROM THE CLID CHIP
*===================
DDRA EQU $04 ; DATA DIRECTION REGISTER OF PORTA:
DDRB EQU $05 ; DATA DIRECTION REGISTER OF PORTB:
DDRC EQU $06 ; DATA DIRECTION REGISTER OF PORTC:
DDRD EQU $07 ; DATA DIRECTION REGISTER OF PORTD:

EVNEN EQU $10 ; EVENT ENABLE REGISTER
*========
INTE1 EQU $6
INTE2 EQU $5
*========

MISC EQU $11 ; MISCELLANEOUS REGISTER
*===================
KEYF EQU $4 ; KEYBOARD INTERRUPT ENABLE
INTF2 EQU $5 ; EXTERNAL INTERRUPT2 ENABLE
INTF1 EQU $6 ; EXTERNAL INTERRUPT1 ENABLE
POR EQU $7 ; POWER ON RESET
*===================

TCR EQU $12 ; TIMER CONTROL REGISTER
*===================
TCMP EQU $0 ; TCMP LOGIC LEVEL CONTROL
IEDG EQU $1 ; SELECTION OF THE EDGE FOR INPUT CAPTURE.
TOIE EQU $5 ; TIMER OVERFLOW INTERRUPT ENABLE
OCIE EQU $6 ; OUTPUT COMPARE INTERRUPT ENABLE
ICIE EQU $7 ; INPUT CAPTURE INTERRUPT ENABLE
*===================

TSR EQU $13 ; TIMER STATUS REGISTER
*===================
TOF EQU $5 ; TIMER OVERFLOW STATUS FLAG
OCF EQU $6 ; TIMER OUTPUT COMPARE STATUS FLAG
ICF EQU $7 ; TIMER INPUT CAP STATUS FLAG
*===================

ICRH EQU $14 ; INPUT CAPTURE REGISTER (HIGH)
ICRL EQU $15 ; INPUT CAPTURE REGISTER (LOW)
OCRH EQU $16 ; OUTPUT COMPARE REGISTER (HIGH)
OCRL EQU $17 ; OUTPUT COMPARE REGISTER (LOW)
TCRH EQU $18 ; TIMER COUNTER REGISTER (HIGH)
TCRL EQU $19 ; TIMER COUNTER REGISTER (LOW)
ACRH EQU $1A ; ALTERNATE COUNTER REGISTER (HIGH)
ACRL EQU $1B ; ALTERNATE COUNTER REGISTER (LOW)
EPRCR EQU $1C ; EPROM CONTROL REGISTER

KBDCR EQU $1F ; KEYBOARD CONTROL REGISTER
*===================
KEYX0 EQU $0
KEYX1 EQU $1
KEYE EQU $7 ; KEYBOARD INTERRUPT ENABLE ON PA0-PA3
*===================
SYSR EQU $2C ; SYSTEM OPTION REGISTER
TCS EQU $5
SCS1 EQU $7
SCS0 EQU $6
INTN1 EQU $4 ; EXTERNAL INTERRUPT LEVEL/EDGE SELECT
INTN2 EQU $3
*****************************************************************
ORG $030 ; RAM EQUATES
*****************************************************************
TEMP RMB 1 ; Temporary register
DATA RMB 1 ; Register for data intake.
TEMPX RMB 1 ; Temporary register for index register.
TEMPA RMB 1 ; Temporary register for accumulator.
COUNT RMB 1
FIVESEC_COUNT RMB 1 ; Counter for 5sec
HIGH_BYTE RMB 1
LOW_BYTE RMB 1
PORTA_IMAGE RMB 1 ; Image register of porta
BIT_COUNTER RMB 1 ; Counter for counting 8bits of data.
BYTE_COUNTER RMB 1 ; Counter for counting data bytes to
; be received.
FLASH_COUNT RMB 1 ; Select the rate of display flashing.
CHECK_SUM RMB 1 ; Byte to store the calculated checksum.
POINTER RMB 1 ; Pointer to store the incoming data
; in temporary buffer
CALL_POS_PTR RMB 1 ; Stores the position of the number stored
CALL_COUNTER RMB 1 ; Stores the value of the total number of
; calls already stored.
MESSAGE_LENGTH RMB 1 ; Register containing the number of data
; bytes to be received.
DATE_TIME_PTR RMB 1 ; Pointer for the date_time_buffer
CALLING_NO_PTR RMB 1 ; Pointer for the calling number buffer.
LCD_ADDR_COUNTER RMB 1 ; Counter for counting the 8 charecter
; for each display line.
TEMP_CALL_COUNTER RMB 1 ; Register for storing the call count
; for review operation
TIME_OUT_COUNTER RMB 1 ; Flag to manage time out during call reception.
PWR_ON_CNTR RMB 1 ; Flag to count 2 seconds after ring detect
; for clid chip power on.
NEW_CALLS RMB 1 ; Holds the number of unseen calls.
*---------------------------------------------------------------------
*REGISTERS USED IN DELETE FUNCTION
SRC_PTR RMB 1 ; Source pointer.Reg to hold the addr of data
; to be moved.
DEST_PTR RMB 1 ; Destination pointer.Reg to hold the addr of
; target buffer to store data.
DIFF_COUNT RMB 1 ; Register to hold the count of the number of
; call datas to be exchenged.
BYTE_EXG_CNT RMB 1 ; Byte exchange counter for transfer of data
; from source to destination.
*---------------------------------------------------------------------
KEY_FUNC_CNTRL RMB 1 ; Stores code of key pressed and the related
*=============== ; functions that are to be executed.
FORWARD_REV EQU $0 ; Review forward key flag
LOCK EQU $1 ; Lock key flag
DEL_KEY EQU $2 ; Delete key flag
REVERSE_REV EQU $3 ; Review backwards key flag
REVIEW EQU $7 ; Bit to scroll forward/reverse.
*=============

TASK_REQUEST1 RMB 1
*=============
KEY_PRESS EQU $0 ; Key switch input.
DISP_NEW_CALL EQU $1 ; Flag to start converting the fresh set of data
DISP_CAPACITY EQU $2 ; Display call capacity of the unit
DISP_DATE_TIME EQU $3 ; Display the stored date and time reading of any
; particular call
NEW_CALL_DT_TIME EQU $4 ; Flag to display the date and time of
; the freshly recd call.
KEY_INT_SENSED EQU $6 ; Process a key function after key debounce.
*===========

USRCNT1 RMB 1 ; User control register one.
PENDING_TASK EQU $0 ; Bit for testing the task pending
SET_FIVE_SEC EQU $1 ; Flag to start counting five seconds.
SET_HALF_SEC EQU $2 ; Flag to enable half sec timeout for data.
ENABLE_KBDINT EQU $3 ; Flag to enable keyboard interrupts
SET_SIX_SEC EQU $4 ; Flag to enable six secs timeout.
TAKE_CHECKSUM EQU $5 ; Flag to take the received byte as checksum.
SDMF_DATA EQU $6 ; Flag to indicate SDMF data to be recd.
;MDMF_DATA EQU $7 ; Flag to indicate MDMF data to be recd.
SET_ONE_SEC EQU $7 ; Flag to enable one sec timeout.
*============

STATUS_FLAG RMB 1 ; Status update of the activities
*============
NO_KEY_PROCESS EQU $0 ; Flag to stop processing key interrupts
FIVE_SEC_OVER EQU $1 ; Flag to indicate expiry of five seconds.
DONT_STOP EQU $2 ; Flag to decide on executing stop instruction.
REV_PHASE_ONE EQU $3 ; Flag to indicate that the display is in first
; 5secs of the review time. The user can lock/unlock
; the number during this period .
LOCK_BIT_STATUS EQU $4 ; Holds the lock/unlock status of a particular
; number.
OUT_CALL EQU $5 ; Flag to indicate call with no number.
RING_DETECT EQU $6 ; Flag to say ring has been detected.
TOGGLE_BIT EQU $7 ; Toggle between two functions
*============

USRCNT2 RMB 1 ; User control register two.
*============
CHK_VALID_RING EQU $0 ; Flag to poll for a valid ring.
ENABLE_CLID_PWR EQU $1 ; Flag to start the counter to give the
; power to the clid chip after 2 seconds of
; ring input.
SENSE_BATT_VOL EQU $2 ; Battery voltage sampling enable flag
FLASH_DISP EQU $3 ; Flash the display.
CHK_KEY_REL EQU $4 ; Flag to test key release.
SET_DISP_FLASH EQU $5 ; Flag to start the display flash counter.
LAST_CALL_OVER EQU $6 ; Flag to indicate last call got deleted
*============

DATE_TIME_BUFFER EQU $100; BUFFER TO STORE THE DATE AND TIME VALUES.
CALLING_NO_BUFFER EQU $53 ; BUFFER TO STORE THE CALLING NUMBERS.
TEMP_DATA_BUFFER EQU $D1 ; BUFFER TO HOLD THE DATA BEFORE STORING .

**********************************************************************
*********************TASK DESCRIPTION TABLE***************************
* *
* TASK NO. REGISTER FUNCTION *
* *
* 1 TASK_REQUEST1 DISPLAY THE NEWLY RECEIVED CALL AND *
* STORE THE CALL IF NECESSARY. *
* 2 TASK_REQUEST1 KEYBOARD INTERRUPT SENSED.COMPARE *
* THE KEYCODE. *
* 3 TASK_REQUEST1 EXECUTE KEY FUNCTION. *
* 4 TASK_REQUEST1 FLASH THE DISPLAY FOR SHOWING UNSEEN*
* CALLS. *
* 5 TASK_REQUEST1 EXECUTE 5SEC TIME OUT TASKS. *
**********************************************************************
ORG $0D00
**********************************************************************
* INITIALIZATION
**********************************************************************
INIT SEI ; Set interrupt mask

* SYSTEM INITIALIZATION
RSP ; Reset stack pointer
BSET TCS,SYSR ; Set the bus cycle timing to fosc/2
BSET SCS1,SYSR
BSET SCS0,SYSR

CLR PORTA
CLR PORTB
CLR PORTD
CLR PORTC
LDA #%00110000 ; key switches (PA5 - PA2) [PA4,PA5 -> ROWS
STA DDRA ; PA3,PA2 -> COLUMNS]

LDA #$FF ; Configure portc as output
STA DDRC ; LCD_ON = BIT6, BUZZ_DRIVE = BIT7

LDA #%00010111 ; Signals connected to PORTD
STA DDRD ; COOK_DATA, RAW_DATA, BATT_LOW,CLID_PWR_UP,
; RDO,LCD_ENABLE, READ/WRITE, REG_SELECT.
*====================================================================
* INITIALIZE INTERRUPT
CLR TCR ; Disable input capture, output compare
BSET TOIE,TCR ; interrupts, Enable timer overflow int.
*=====================================================================
BCLR INTE1,EVNEN ; Disable external interrupt1
BCLR INTE2,EVNEN ; Disable external interrupt2
BCLR KEYE,KBDCR ; Disable keyboard interrupt. Enable
; the interrupts after display of '25 CALLS'
; message.
*=====================================================================
* CLEAR THE RAM VAIRABLES
CLRA
CLRX
FILL STA TEMP,X ; Clear is the ram variables and also the
STA DATE_TIME_BUFFER,X; Date and time storing locations .
INCX ; fill zeroes into 100 locations
CPX #$64 ; starting from address 30h and 100h.
BLS FILL
*====================================================================
JSR INIT_LCD_DISPLAY ; Initialise the lcd display
*====================================================================
* Blank the first four characters of the display.
* Put the logo " CRYSTAL" on the display.

CLRX
NEXT_LETR
LDA CRYSTAL_LOGO,X ; Read the ASCII table containing the values
CMP #'*' ; required for displaying the logo.
BEQ CH_OVER ; Write the data to the display.
JSR FILL_DATA ; Keep filling the display until a'*'is
INCX ; fetched.
BRA NEXT_LETR
*--------------------------------------------------------------------
CH_OVER
BSET SET_FIVE_SEC,USRCNT1 ; Set flag to count five seconds.
BSET DISP_CAPACITY,TASK_REQUEST1; Set the flag to display the capacity.
BSET CLID_CHIP_PWR,PORTD ; Power off the CLID IC 145447.
BSET PENDING_TASK,USRCNT1 ; Set flag for task processing.
BCLR BUZZ_DRIVE,PORTC ; Disable buzzer drive

CLI ; Enable the interrupts.
*********************************************************************
* Main loop continuously checks for any pending tasks. If a task
* is pending, identifies the task and completes.

MAIN BRSET PENDING_TASK,USRCNT1,EXIT_LOOP; Check the task execution bit
; of the USRCNT1 register.
BRSET DONT_STOP,STATUS_FLAG,MAIN ; Check if the timer is on. If
; it is running dont stop.
CLR DDRB ; Config portb lines as input
; before stopping.
BCLR TOIE,TCR ; Disable timer interrupts
BCLR NO_KEY_PROCESS,STATUS_FLAG ; Enable key board scanning.
BCLR CHK_KEY_REL,USRCNT2
STOP
BRA MAIN
*---------------------------------------------------------------------
EXIT_LOOP
CLR LCD_ADDR_COUNTER ; Counter for the address switchover
; from line1 to line2 is cleared.
LDA #$80 ; Put the address of the RD ram
JSR STORE_AND_CHK_BUSY ; line1 of the display.

JSR DECODE_TASK ; Decode the task.
BRA MAIN
***********************************************************************

DECODE_TASK
BRSET SET_FIVE_SEC,USRCNT1,CHK_FIVE_SEC; Check if any five seconds
; waiting task is pending.
BCLR PENDING_TASK,USRCNT1 ; Clear the task execution bit.

CHK_FIVE_SEC
BRSET DISP_NEW_CALL,TASK_REQUEST1,TASK_1; Store the call NO. into the
; ram.
BRSET KEY_INT_SENSED,TASK_REQUEST1,TASK_2; Key interrupt recognised.
BRSET KEY_PRESS,TASK_REQUEST1,TASK_3 ; Key function pending.
BRSET FLASH_DISP,USRCNT2,TASK_4 ; Display needs to be flashed

BRSET FIVE_SEC_OVER,STATUS_FLAG,TASK_5; If FIVE seconds has expired
RTS ; switch to the next task.
*======================================================================
TASK_1 JSR INIT_LCD_DISPLAY ; Initialise the display.
JSR DISPLAY_NEW_CALL_NO. ; Shift the data from the temporary
; buffer and store into the data ram.
LDA #$05
STA COUNT
JMP TOGGLE_BUZZER ; Give five beeps.

*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
TASK_2 BCLR KEY_INT_SENSED,TASK_REQUEST1
JMP FIND_KEY ; Identify the key code.
*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
TASK_3 BCLR KEY_PRESS,TASK_REQUEST1; Clear the key_press flag.
BSET PENDING_TASK,USRCNT1
CLR FIVESEC_COUNT

BRSET SET_FIVE_SEC,USRCNT1,NO_LCD_INIT; If a key is pressed
; within five seconds of the previous
; key press, display need not be initialised.
JSR INIT_LCD_DISPLAY ; Initialise the lcd display.

LDA CALL_COUNTER ; For review forward and review reverse
STA TEMP_CALL_COUNTER ; Store the call count into a temp reg.
GO_AHEAD
BSET REVIEW,KEY_FUNC_CNTRL; Set flag to indicate review is on.
JSR DISP_CALL_NO ; Display the number of calls stored.
JMP BUZZ ; Give a beep.

*=====================================================================
TASK_4 BCLR FLASH_DISP,USRCNT2 ; Clear the display flash bit.
JMP DISP_CALL_NO ; Flash the unseen call number
; on the display.
*=====================================================================
TASK_5 BCLR FIVE_SEC_OVER,STATUS_FLAG; Clear the FIVE seconds expiry flag.
JMP SWITCH_FIVE_SEC_TASK ; Change the five_sec tasks
*=====================================================================
REWIEW_KEYS_PRESS
LDA CALL_COUNTER ; If all the calls are deleted or if no
BNE PROCEED ; calls are left in the memory,exit.
JMP BUZZ ; No calls are present.
*----------------------------------------------------------------------
PROCEED
BRCLR REV_PHASE_ONE,STATUS_FLAG,NO_LOCK_DELETE;If it is not the first
; 5 secs of the review time don't lock/unlock.
BRCLR LOCK,KEY_FUNC_CNTRL,CHK_DELETE; Check if the number selected
; is to be locked or unlocked.
JSR CHECK_LOCK_UNLOCK ; Check the lock bit corresponding to that.
BRA SET_DT_TIME_DISP_FLAG ; NO.
*-------------------------------------------------------------------------
CHK_DELETE
BRCLR DEL_KEY,KEY_FUNC_CNTRL,NO_LOCK_DELETE; Check if the number being
; displayed to be deleted.
BRCLR LOCK_BIT_STATUS,STATUS_FLAG,DELETE_; If the present call is
RTS ; locked, no delete happens.
DELETE_ BRCLR LAST_CALL_OVER,USRCNT2,PROCEED_DEL; If already the last
JMP BUZZ ; call is deleted,exit.
PROCEED_DEL
JSR DELETE_NUMBER ; Delete the number stored.
BRCLR LAST_CALL_OVER,USRCNT2,PROCEED_; Check if it was the last call.
JMP BUZZ ; If that was the last call, dont search
PROCEED_ BRA PUT_NEXT_NO ; for the next number.

*-------------------------------------------------------------------------
NO_LOCK_DELETE
BRCLR DISP_DATE_TIME,TASK_REQUEST1,PHASE1;Check if phase one of the
; review sequence is already on.
JSR PUT_STORED_DATE ; If phase1 is already on, put the date
; and time of the call for the next review
; press.
JMP BUZZ ; Toggle_buzzer.
PHASE1
BRSET REVERSE_REV,KEY_FUNC_CNTRL,REV_REVERSE; Compare the code for
; review keys.

*==REVIEW NUMBERS IN FORWARD DIRECTION===*
BRSET FORWARD_REV,KEY_FUNC_CNTRL,FF_REVIEW; Compare the code for rev
; forward key.
JMP NO_REVIEW
FF_REVIEW
LDA TEMP_CALL_COUNTER ; Findout if all the numbers have
CMP CALL_COUNTER ; been exhausted.
BLO NEXT_NUMBER
LDA #$01
BRA LOAD_FIRST
NEXT_NUMBER
INC TEMP_CALL_COUNTER
BRA SET_DT_TIME_DISP_FLAG

REV_REVERSE
LDA TEMP_CALL_COUNTER
CMP #$01 ; Check if the counter has the least
BLS LOAD_LAST ; count.If yes, scroll from the last.
DEC TEMP_CALL_COUNTER ; Set the counter for the next call.
BRA SET_DT_TIME_DISP_FLAG
LOAD_LAST
LDA CALL_COUNTER
LOAD_FIRST
STA TEMP_CALL_COUNTER
*----------------------------------------------------------------------
SET_DT_TIME_DISP_FLAG
BCLR LAST_CALL_OVER,USRCNT2
BSET REV_PHASE_ONE,STATUS_FLAG; Set the phase one timeflag in the
; STATUS_FLAG register.
BSET DISP_DATE_TIME,TASK_REQUEST1; Set flag to display date and
; time after five seconds
BCLR SET_DISP_FLASH,USRCNT2; If the display is flashing,stop it.
BCLR FLASH_DISP,USRCNT2 ; Clear the display flash bit.

PUT_NEXT_NO
LDA TEMP_CALL_COUNTER ; Display the call number
STA TEMPA
JSR PUT_CALL_NO

LDA #$20 ; Put a blank charecter after the number.
JSR FILL_DATA

LDA TEMP_CALL_COUNTER ; Get the DAY reading. Bit 7 of DAY
LDX #$04 ; reading has the information of
MUL ; NEW CALL
SUB #$04
TAX
INCX
LDA DATE_TIME_BUFFER,X ; Read the New call info from bit 7
STA TEMPA
BRCLR 7,TEMPA,NOT_NEW ;
BCLR 7,TEMPA ; Clear the new call indication
LDA TEMPA
STA DATE_TIME_BUFFER,X ;
DEC NEW_CALLS ; Reduce the new call counter.
LDA #'*' ; Char '*' is the new call indicator.
BRA WRTE_L

NOT_NEW
JSR READ_LOCK_BIT ; Read the corresponding lock bit.
BRCLR LOCK_BIT_STATUS,STATUS_FLAG,NO_LOCK

LDA #$4C ; Display 'L' for lock.
BRA WRTE_L

NO_LOCK LDA #$20 ; If not lock put blank.
WRTE_L JSR FILL_DATA

LDA #$20 ; Put one more blank character.
JSR FILL_DATA

LDA TEMP_CALL_COUNTER
LDX #$05 ; Store the count for the number of bytes
STX COUNT ; to be read from the buffer.
MUL ; Multiply the temp_call_counter value
SUB #$05 ; with 5 to get the pointer value .
TAX

BUZZ LDA #!01
STA COUNT
JMP TOGGLE_BUZZER ; Beep the buzzer once.

NO_REVIEW RTS
*=====================================================================
* INIT_LCD_DISPLAY :
* Initialises the LCD display for dual line, 8bit mode. The font size
* selected is 5*7.
*
* The initialisation is done in the following way.
* 1. The reset instruction is loaded to the display three times. A
* delay of 100ms is given after each reset instruction.
* 2. The reset instruction for the fourth time is loaded with the
* selection of the font, data width, number of lines . After
* this the busy flag status is read from the display. The program
* will wait in a loop till the busy flag gets cleared.
* 3. In the next instruction display is switched off.
* 4. Display blank command is given next.
* 5. Entry mode command is given next.
* 6. The next instruction contains the display mode set, switches off
* the cursor.
* 7. Instruction for setting shift mode is given next.
*======================================================================
INIT_LCD_DISPLAY
LDA #$FF ; Configure portb lines as outputs .
STA DDRB

BCLR LCD_ON,PORTC ; Power on the lcd module

LDA #%00110000 ; Initial reset instruction
JSR STORE_INST
JSR DELAY_100MS

LDA #%00110000 ; Initial reset instruction
JSR STORE_INST
JSR DELAY_100MS

LDA #%00110000 ; Initial reset instruction
JSR STORE_AND_CHK_BUSY

LDA #%00111000 ; Set for 8bits of data, dual line
JSR STORE_AND_CHK_BUSY ; display font size 5*7.

LDA #%00001000 ; Switch off the display
JSR STORE_AND_CHK_BUSY

LDA #%00000001 ; Display blank instruction is given next.
JSR STORE_AND_CHK_BUSY

LDA #%00000111 ; Give entry mode set command.
JSR STORE_AND_CHK_BUSY

LDA #%00001100 ; Display mode set,make lcd pattern,
JSR STORE_AND_CHK_BUSY ; cursor & blink off

LDA #%00000110 ; Set shift mode.
JSR STORE_AND_CHK_BUSY

RTS
*=================================================================
* Stores the accumulator contents to the display and checks the
* busy flag before coming out of the routine.
STORE_AND_CHK_BUSY
JSR STORE_INST ; Store the ACC contents in display.
JMP CHECK_BUSY_FLAG ; Read the busy flag of the display.
*=================================================================
STORE_INST
BCLR RD_WR,PORTD ; Make R/W signal low
BSET LCD_ENABLE,PORTD ; Make the enable signal high.
STA PORTB
BCLR LCD_ENABLE,PORTD ; Make the enable signal low.
BSET RD_WR,PORTD ; Make R/W signal high
RTS
*==================================================================
* Reads the busy flag bit of the lcd display. If the bit is clear
* ( not busy ), comes out of the routine else waits in the loop
* till it is clear.

CHECK_BUSY_FLAG
CLR DDRB
BCLR REG_SEL,PORTD ; Configure PORTB as input to read the status.
BSET RD_WR,PORTD ; Make enable and R/W signals high and RS low.
BSET LCD_ENABLE,PORTD

RETRY
**** if no busy time out here with an error flag

BRSET 7,PORTB,RETRY ; Check if the busy flag is clear.if set,
; wait till it becomes clear.
BCLR LCD_ENABLE,PORTD
BCLR RD_WR,PORTD ; Make the control signals low.

LDA #$FF ; Reconfigure PORTB as output.
STA DDRB

RTS
*=================================================================
* Writes the data to be displayed on the lcd. First sets RS to
* logic 1, stores the data and restores the status of
* the control signals after checking for busy.

FILL_DATA
BSET REG_SEL,PORTD ; Set RS bit high

JSR STORE_AND_CHK_BUSY ; Store the contents of the ACC into the
; display.
INC LCD_ADDR_COUNTER
LDA LCD_ADDR_COUNTER
CMP #$08 ; Check if 8 bytes have been loaded.
BNE SAME_RD_ADDR ; if yes, change to line2 of the display.

LDA #%11000000 ; Set RD ram address to second line.
JSR STORE_AND_CHK_BUSY

SAME_RD_ADDR RTS

*================================================================
* Split the hex value into two , add 30h for both of them.

CONVERT_HEX_BCD
CLR TEMP
CMP #$0A
BHS CONVERT
BRA ADD_

CONVERT INC TEMP
SUB #$0A
CMP #$0A
BHS CONVERT

LDX TEMP
JSR SHIFT_LEFT
STX TEMP
ORA TEMP
ADD_ JMP SPLIT_AND_ADD30 ; convert to ASCII.
*================================================================
STORE_DATA
LDA HIGH_BYTE
JSR FILL_DATA

LDA LOW_BYTE
JMP FILL_DATA
*================================================================
SHIFT_RIGHT
LSRA
LSRA
LSRA
LSRA
RTS
*=================================================================
* Left shifts the contents of the X register four times.
SHIFT_LEFT
LSLX
LSLX
LSLX
LSLX
RTS
*================================================================
* The contents of the accumulator is split into two, 30h is added
* for both to convert into ascii.

SPLIT_AND_ADD30
STA LOW_BYTE
AND #$F0 ; Mask the lower nibble and shift
JSR SHIFT_RIGHT ; the upper nibble to right 4times .
CMP #$0F ; Test if 0F was stored which indicates
BNE MASK_UPPER ; a blank character was received as data.
LDA #$20 ; If yes, put the value 20h which is
BRA ST_SPACE ; ascii blank.
MASK_UPPER
ADD #$30 ; If not blank character, add 30h.
ST_SPACE
STA HIGH_BYTE
LDA LOW_BYTE
AND #$0F ; Read the lower nibble and compare with
CMP #$0F ; the value 0F. If yes put a blank char.
BNE MASK_LOWER
LDA #$20
BRA ST_SPACE1
MASK_LOWER
ADD #$30
ST_SPACE1 STA LOW_BYTE
JMP STORE_DATA
*================================================================
CHECK_LOCK_UNLOCK
JSR READ_LOCK_BIT; Read the lock bit of the corresponding no
; to decide whether to lock or unlock.
BRSET LOCK_BIT_STATUS,STATUS_FLAG,CLR_LOCK
BSET LOCK_BIT_STATUS,STATUS_FLAG; Set the lock flags.
BSET 7,TEMPA
BRA STORE_BIT

CLR_LOCK
BCLR LOCK_BIT_STATUS,STATUS_FLAG
BCLR 7,TEMPA
STORE_BIT
LDA TEMPA
STA DATE_TIME_BUFFER,X; store the bit in the register back

RTS
*======================================================================
* NUMBER LOCK INFO IS STORED IN THE BIT 7 OF THE BYTE CONTAINING
* THE DATE INFORMATION
READ_LOCK_BIT
LDA TEMP_CALL_COUNTER ; Find the bit position of the
JSR GET_DATE_TIME_INDEX
BRSET 7,TEMPA,NUM_LOCK; buffer.
BCLR LOCK_BIT_STATUS,STATUS_FLAG
RTS
NUM_LOCK BSET LOCK_BIT_STATUS,STATUS_FLAG; Set flag to indicate present
; number has been locked
RTS
*====================================================================
GET_DATE_TIME_INDEX
LDX #$04
MUL
SUB #$04
TAX
LDA DATE_TIME_BUFFER,X; Read the lock info from bit 7
STA TEMPA ; of the first byte of the date_time
RTS
*========================================================================
* This routine is called if there are no calls store in the unit.
* The routine reads the ascii data for displaying "no call" from
* the table and writes into the display.
NO_CALL_MESSAGE
CLRX
NEXT_LETR2
LDA NO_CALL,X
CMP #'*'
BEQ CH_OVER2
STX TEMPX
JSR FILL_DATA
LDX TEMPX
INCX
BRA NEXT_LETR2
CH_OVER2 RTS
*=====================================================================
DELETE_NUMBER
BCLR DISP_DATE_TIME,TASK_REQUEST1;
CLR FIVESEC_COUNT

LDA CALL_POS_PTR ; If the position counter is already
BNE REDUCE_COUNT ; pointing to the very first location,
BRA NO_COUNT_REDUCT ; no decrement takes place.
REDUCE_COUNT
DEC CALL_POS_PTR
NO_COUNT_REDUCT
LDA CALL_COUNTER ; Check if the call being displayed
SUB TEMP_CALL_COUNTER ; is the last one.
BNE NOT_LAST_NUMBER
CLRX
NEXT_LETR3
LDA LAST_CALL_DELETE,X; Read the ASCII table for the
CMP #'*'
BEQ CH_OVER3
STX TEMPX ; last call delete message.
JSR FILL_DATA
LDX TEMPX
INCX
BRA NEXT_LETR3
CH_OVER3
BSET LAST_CALL_OVER,USRCNT2; Flag set to indicate the last call
LDA TEMP_CALL_COUNTER
LDX #$4 ; Clear the location containing
MUL ; the lock/unlock information
SUB #$4 ; so that the next coming call can
TAX ; get stored in that place
BRA DEL_OVER
*-----------------------------------------------------------------------
NOT_LAST_NUMBER
STA TEMPA
STA DIFF_COUNT ; Store the count of the number of
LDA TEMP_CALL_COUNTER ; call datas to be exchanged.
LDX #$5
MUL
STA SRC_PTR ; Get the address of the next call data.
SUB #$5
STA DEST_PTR ; Set dest ptr to the call that is to be
; erased.
FRESH_SET
LDA #$5 ; Total number of bytes per calling no
STA BYTE_EXG_CNT ; is store in byte_exg_cnt.
EXCHANGE
LDX SRC_PTR
LDA CALLING_NO_BUFFER,X
LDX DEST_PTR
STA CALLING_NO_BUFFER,X
INC SRC_PTR
INC DEST_PTR
DEC BYTE_EXG_CNT
BNE EXCHANGE
DEC DIFF_COUNT
BNE FRESH_SET
*-----------------------------------------------------------------------
* Exchange the date and time datas.

LDA TEMPA
STA DIFF_COUNT ; Store the count of the number of

LDA TEMP_CALL_COUNTER ; call datas to be exchanged.
LDX #$4
MUL
STA SRC_PTR ; Get the address of the next call data.
SUB #$4
STA DEST_PTR ; Set dest ptr to the call that is to be
; erased
FRSH_SET
LDA #$4 ; Total number of bytes per calling no
STA BYTE_EXG_CNT ; is store in byte_exg_cnt
EXCH LDX SRC_PTR
LDA DATE_TIME_BUFFER,X
LDX DEST_PTR
STA DATE_TIME_BUFFER,X
INC SRC_PTR
INC DEST_PTR
DEC BYTE_EXG_CNT
BNE EXCH
DEC DIFF_COUNT
BNE FRSH_SET
LDX DEST_PTR ; Fill zero into the next call
DEL_OVER ; location.
CLRA
STA DATE_TIME_BUFFER,X
DEC CALL_COUNTER ; Reduce the number of call count.
RTS
*================================================================
* Blanks the display for the number of characters loaded in the count
* register.The value 20h is the ASCII value for blank .

BLANK_DISP
NOT_OVER LDA #$20
JSR FILL_DATA
DEC COUNT
BNE NOT_OVER
RTS
*=====================================================================
* Switch the buzzer on and off for as many times as the value loaded
* into the count register each after a gap of 100ms.
TOGGLE_BUZZER
RELOAD BSET BUZZ_DRIVE,PORTC ; Enable buzzer drive
JSR DELAY_100MS
BCLR BUZZ_DRIVE,PORTC ; Disable buzzer drive
JSR DELAY_100MS
DEC COUNT
BNE RELOAD
RTS
*=====================================================================
DISP_CALL_NO
BSET SENSE_BATT_VOL,USRCNT2 ; Set the batt sense flag.
LDA CALL_COUNTER
BNE CALLS_PRESENT
JMP NO_CALL_MESSAGE ; Display "NO CALL" message.
CALLS_PRESENT
STA TEMPA ; If calls are present show
JSR PUT_CALL_NO ; call number.

LDA NEW_CALLS ; Check if any of the calls
BEQ NO_NEW_CALLS ; are not yet seen.
STA TEMPA ;

LDA #!10 ; Display the unseen calls
STA COUNT ; on the extreme right.
JSR BLANK_DISP

BSET OCIE,TCR ; Enable the output compare int
BSET SET_DISP_FLASH,USRCNT2 ; to count for the flashing rate.
BRSET TOGGLE_BIT,STATUS_FLAG,PUT_DIGIT; Check if ' ' or digits
; is to be displayed.
BSET TOGGLE_BIT,STATUS_FLAG ; Set the toggle bit.
LDA #$03
STA COUNT
JMP BLANK_DISP ; Blank the portion of the display.

PUT_DIGIT BCLR TOGGLE_BIT,STATUS_FLAG; Clear the toggle bit.
BRA PUT_CALL_NO ; Display the Newcalls count.
NO_NEW_CALLS RTS
*---------------------------------------------------------------------
PUT_CALL_NO
LDA #$43 ; Put 'C' on the display.
JSR FILL_DATA

LDA TEMPA
JMP CONVERT_HEX_BCD ; Display the CALL NUMBER on the lcd
*======================================================================
SWITCH_FIVE_SEC_TASK
BRSET NEW_CALL_DT_TIME,TASK_REQUEST1,DISP_NEW_TIME

BRSET DISP_DATE_TIME,TASK_REQUEST1,PUT_STORED_DATE
BRSET ENABLE_KBDINT,USRCNT1,SET_KEYBOARD_INT
BRSET DISP_CAPACITY,TASK_REQUEST1,STORAGE_CAPACITY
BRA SWITCH_DISP_OFF
*----------------------------------------------------------------------
STORAGE_CAPACITY
BCLR DISP_CAPACITY,TASK_REQUEST1
CLRX
NEXT_LETR1
LDA CALL_LOGO,X ; Display the message " 25 CALLS"
CMP #'*' ; on the display.
BEQ CH_OVER1
JSR FILL_DATA
INCX
BRA NEXT_LETR1
CH_OVER1
BSET ENABLE_KBDINT,USRCNT1; Enable keyboard interrupts after
; five seconds gap for the display
JMP SET_BATT_SAMPLE ; of storage capacity.
*===================================================================
PUT_STORED_DATE
BCLR DISP_DATE_TIME,TASK_REQUEST1; Clear the task_request flag.
BCLR REV_PHASE_ONE,STATUS_FLAG ; Clear the phase one timeflag.
; End of the time period for lock/unlock.
BCLR NO_KEY_PROCESS,STATUS_FLAG; Enable for key processing if
BCLR CHK_KEY_REL,USRCNT2 ; the key processing was stopped while
JMP RECALL_STORED_DT_TIME; processing a new call.
*======================================================================
SET_KEYBOARD_INT
BCLR ENABLE_KBDINT,USRCNT1
BSET SENSE_BATT_VOL,USRCNT2; Set flag to sense battery voltage.
BCLR INTF1,MISC
BCLR INTF2,MISC
BSET INTN1,SYSR ; Select negative edge trigger for ring
; detect interrupt.
BSET INTE1,EVNEN ; Enable external interrupt1
*----------------------------------------------------------------------
BCLR ROW1,PORTA ; Make the row outputs low to recognise
BCLR ROW2,PORTA ; the keyboard interrupts.

BCLR KEYF,MISC
BSET KEYE,KBDCR ; Enable keyboard interrupt
BCLR KEYX0,KBDCR
BCLR KEYX1,KBDCR
*----------------------------------------------------------------------
SWITCH_DISP_OFF
BCLR SET_DISP_FLASH,USRCNT2; Clear the display flashing enable bit.
BCLR NO_KEY_PROCESS,STATUS_FLAG; Enable for key processing.
BCLR CHK_KEY_REL,USRCNT2
BCLR REVIEW,KEY_FUNC_CNTRL ; Clear the review bit in the
; KEY_FUNC_CNTRL register.
BRCLR SENSE_BATT_VOL,USRCNT2,DISP_SHUT_OFF; Check if battery has
; to be sampled.
BCLR SENSE_BATT_VOL,USRCNT2; Clear the batt sense flag
BRSET BATT_LOW,PORTD,DISP_SHUT_OFF; Read port pin connected to batt.
JSR PUT_BAT_LOW ; Indicate battery low .
BRA RETURN
DISP_SHUT_OFF
BCLR SET_FIVE_SEC,USRCNT1 ; Clear the five seconds flag.
LDA #%00001000 ; Give command to switch off the display.
JSR STORE_AND_CHK_BUSY
BSET LCD_ON,PORTC ; Power off the lcd module.
RETURN RTS
*======================================================================
DISP_NEW_TIME
BCLR NEW_CALL_DT_TIME,TASK_REQUEST1;
LDX #$4
JSR FETCH_TWO_BYTES ; Get the hour reading

LDA #$3A ; Display a colon.
JSR FILL_DATA

LDX #$6 ; Get the MINUTES reading
JSR FETCH_TWO_BYTES

LDA #$2 ; Blank two characters.
STA COUNT
JSR BLANK_DISP

BRSET OUT_CALL,STATUS_FLAG,NO_POS_DISP; Dont display any position
LDA CALL_POS_PTR ; of storage for outside call.
STA TEMPA
JSR PUT_CALL_NO ; Display the call number for which date
LDA #$01
BRA BLNK
NO_POS_DISP
LDA #$4
BLNK STA COUNT
JSR BLANK_DISP

LDX #!2
JSR FETCH_TWO_BYTES ; Fetch the DAY reading from the buffer.

BCLR OUT_CALL,STATUS_FLAG; Clear the flag indicating out call.
JMP SET_BATT_SAMPLE
*=====================================================================
RECALL_STORED_DT_TIME
LDA TEMP_CALL_COUNTER; Get the pointer for the date and
LDX #$04 ; time buffer.
MUL
SUB #$04
TAX
*-----------------------------------------------------------------------
* Date and time values are stored in the buffer in the following
* order MONTH, DAY, HOUR, MINUTES. The display should display
* the same in HOUR, MINUTE, DAY, MONTH order.

* Get the hour reading
INCX
INCX
LDA DATE_TIME_BUFFER,X
STX TEMPX

STA TEMPA ; Store the value in a temp reg.
AND #$F0
JSR SHIFT_RIGHT
BNE CONVERT_D
LDA TEMPA
BRA RETAIN

CONVERT_D STA COUNT
LDA TEMPA
SUBRACT SUB #!6
DEC COUNT
BNE SUBRACT

CLR COUNT
CMP #$0C
BLS COMP_9
SUB #$0C

COMP_9 CMP #$09
BLS RETAIN ; Since the received time is the absolute
ONCE_MORE
SUB #$0A ; reading check if the value has to be
INC COUNT ; subtracted with 12.
CMP #$09
BHI ONCE_MORE
LDX COUNT
STA COUNT
JSR SHIFT_LEFT
TXA
ORA COUNT

RETAIN JSR SPLIT_AND_ADD30

LDA #$3A ; Display a colon.
JSR FILL_DATA

LDX TEMPX
INCX
LDA DATE_TIME_BUFFER,X; Fetch the minute reading and display.
STX TEMPX
JSR SPLIT_AND_ADD30

LDA TEMPA
CMP #$12
BLS AM
LDA #$50
BRA AM_PM_
AM LDA #$41
AM_PM_ JSR FILL_DATA ; Display the AM/PM value.

LDA #$20 ; Blank one charecter.
JSR FILL_DATA

LDA TEMP_CALL_COUNTER ; Display the call number for which date
STA TEMPA
JSR PUT_CALL_NO ; and time are displayed .

LDA #$20 ; Blank one charecter.
JSR FILL_DATA

LDX TEMPX
DECX
DECX
LDA DATE_TIME_BUFFER,X; Fetch the DAY reading from the buffer.
STX TEMPX
JSR SPLIT_AND_ADD30
LDA #$2E ; Put a FULLSTOP next.
JSR FILL_DATA

LDX TEMPX
DECX
LDA DATE_TIME_BUFFER,X; Fetch the month reading and display.
AND #$7F ; Bit 7 contains the lock information.
JSR SPLIT_AND_ADD30

SET_BATT_SAMPLE
BSET SENSE_BATT_VOL,USRCNT2; Set flag to enable battery
; voltage sampling in the next five_sec
RTS
*=====================================================================
FETCH_TWO_BYTES
LDA TEMP_DATA_BUFFER,X; Fetch two bytes of data from the
STX TEMPX ; temp buffer and display. At this
JSR FILL_DATA ; point of time a decision to store
; the received data is not taken.
LDX TEMPX
INCX
LDA TEMP_DATA_BUFFER,X
JMP FILL_DATA
*=====================================================================
DISPLAY_NEW_CALL_NO.
BCLR DISP_NEW_CALL,TASK_REQUEST1
CLR FIVESEC_COUNT
BSET SET_FIVE_SEC,USRCNT1
BSET NEW_CALL_DT_TIME,TASK_REQUEST1
BSET PENDING_TASK,USRCNT1
BCLR FLASH_DISP,USRCNT2 ; Clear the display flash bit.
BCLR SET_DISP_FLASH,USRCNT2; Clear the display flashing enable bit.

;; BCLR DISP_DATE_TIME,TASK_REQUEST1; Clear flag to prevent any
; pending date and time display
; of already stored calls.
LDA MESSAGE_LENGTH ; Compare the message length
CMP #$09 ; with 10.if not greater call need
BHI _CALL_STORE ; not be stored. Display outside
; call.
BSET OUT_CALL,STATUS_FLAG ; Set flag to indicate that no
JMP DISP_PAY_PHONE ; storage position to be shown.
*-------------------------------------------------------------------
_CALL_STORE
CLR DATE_TIME_PTR
LDA CALL_POS_PTR ; If already 25 calls are stored
CMP #!25 ; call counter is not incremented
BEQ WRAP_OVER

NO_CALL_INCREMENT
BRA CALCULATE_INDEX

WRAP_OVER CLR CALL_POS_PTR
CALCULATE_INDEX
LDA CALL_POS_PTR ; Read the lock status of the call
INCA ; stored in the location pointed by
JSR GET_DATE_TIME_INDEX ; call_pos_ptr. If the call happens
BRCLR 7,TEMPA,LOCK_BIT_CLR; to be locked,scan the next call.
INC CALL_POS_PTR
LDA CALL_POS_PTR
CMP #!25
Bne INCR_LOOP_COUNTER
CLR CALL_POS_PTR

INCR_LOOP_COUNTER
INC DATE_TIME_PTR ; Date_time_ptr is used as a loop
LDA DATE_TIME_PTR ; counter. Scan for 25 calls. If
CMP #!25 ; all the calls are locked,exit.
BNE CALCULATE_INDEX
JSR FLASH_NEW_CALL ; Display the new call number.Do
BSET OUT_CALL,STATUS_FLAG ; Set flag to indicate that no
JMP DISP_NO_SPACE ; call store.
LOCK_BIT_CLR
LDA CALL_POS_PTR
LDX #$5 ; Find the location for storing
MUL ; the calling number.
STA CALLING_NO_PTR

LDA CALL_POS_PTR
LDX #$4 ; Find the location for storing
MUL ; the date and time.
STA DATE_TIME_PTR

INC CALL_POS_PTR

LDA CALL_POS_PTR ; Display the position of the
STA TEMPA ; call storage.
JSR PUT_CALL_NO

LDA #$3
STA COUNT
JSR BLANK_DISP
JSR FLASH_NEW_CALL ; Display the new call number
; before going into recording the
; number in the call storage ram.
*====================================================================
* PACK AND STORE THE DATA
CLR COUNT
CLRX
READ_BYTE
LDA TEMP_DATA_BUFFER,X ; Read the data from the temp buffer
CMP #$20 ; If the data byte is an ascii blank,
BNE NEGLECT ; (20h) store 0F as signature. While
LDA #$0F ; reading the data, if 0F is read,
; convert to ascii blank.
NEGLECT AND #$0F ; Discard the upper nibble.
STX TEMPX
TAX
JSR SHIFT_LEFT ; Shift the lower nibble left four times.
STX TEMPA
LDX TEMPX
INCX
LDA TEMP_DATA_BUFFER,X ; Read the next data byte from the temp
; buffer
CMP #$20
BNE NEGLECT1
LDA #$0F
NEGLECT1 AND #$0F
ORA TEMPA
STA TEMPA

INCX
STX TEMPX

LDX COUNT ; Check if the first four bytes have
CPX #$03 ; been stored already.The first four
BHI NUMBER_STORAGE ; bytes corresponds to date and time.

CPX #!01
BNE NOT_DAY
BSET 7,TEMPA
LDA TEMPA
NOT_DAY LDX DATE_TIME_PTR ; Store the data into the date_time
STA DATE_TIME_BUFFER,X ; buffer.
INC COUNT
INC DATE_TIME_PTR
BRA COMP_MESSAGE_LENGTH
NUMBER_STORAGE
LDX CALLING_NO_PTR ; Store the message into the calling
STA CALLING_NO_BUFFER,X ; number storage buffer.
INC CALLING_NO_PTR

COMP_MESSAGE_LENGTH
LDX TEMPX ; Check if all the bytes have been
CPX MESSAGE_LENGTH ; converted and stored.
BHS CHK_CALL_NO
BRA READ_BYTE ; Read the next two bytes.
CHK_CALL_NO
LDA NEW_CALLS
CMP #!25
BHS OUT_OF_LIMIT
INC NEW_CALLS ; Update the unseen call counter.
OUT_OF_LIMIT RTS

*=====================================================================
FLASH_NEW_CALL
LDX #!08 ; fetch the number from the temp
FETCH_BYT LDA TEMP_DATA_BUFFER,X; buffer and display.
STX TEMPX
JSR FILL_DATA
LDX TEMPX
INCX
CPX #!18
BNE FETCH_BYT
RTS
*====================================================================
DISP_PAY_PHONE
LDX #!08
LDA TEMP_DATA_BUFFER,X
CLRX
CMP #'P'
BEQ PAY_PHONE

NEXT_LETR5
LDA OUT_PH,X ; Read the ASCII table containing the values
CMP #'*' ; required for displaying the logo.
BEQ CH_OVER4 ; Write the data to the display.
JSR FILL_DATA
INCX
BRA NEXT_LETR5

*------------------------------------------------------------------
PAY_PHONE
NEXT_LETR4
LDA PAY_PH,X ; Read the ASCII table containing the values
CMP #'*' ; required for displaying the logo.
BEQ CH_OVER4 ; Write the data to the display.
JSR FILL_DATA
INCX
BRA NEXT_LETR4

CH_OVER4 RTS
*==================================================================
DISP_NO_SPACE ; Display non availability of space.
CLRX
NEXT_CHAR1
LDA NO_SPACE,X ; Read the ASCII table containing the values
CMP #'*' ; required for displaying the message .
BEQ CH_FINISH ; Write the data to the display.
JSR FILL_DATA
INCX
BRA NEXT_CHAR1

CH_FINISH RTS
*====================================================================
FIND_KEY
JSR DELAY_100MS ; Debounce delay.
LDA PORTA ; Test if any of the keys are pressed.
AND #%00001100
CMP #$0C
BEQ EXIT_COMP

CLRX ; Set x=0 as index of table look up at KEYTBL.
LDA PORTA
AND #%11000011
STA PORTA_IMAGE
LOOP_K1
LDA KEYTBL,X ; Test which key is pressed.
ORA PORTA_IMAGE

STA PORTA
CMP PORTA
BEQ FOUND
INCX ; Testing of next key
INCX
CPX #$8
BLO LOOP_K1
BRA EXIT_COMP

FOUND INCX
LDA KEY_FUNC_CNTRL
AND #$F0
ORA KEYTBL,X ; Load the key code from the look_up table.
STA KEY_FUNC_CNTRL
BSET KEY_PRESS,TASK_REQUEST1; Set flag for key pressed on the keypad
BSET CHK_KEY_REL,USRCNT2 ; Set flag to check for key release.
BSET PENDING_TASK,USRCNT1 ; Set flag for key processing.
JSR RELOAD_TIMER ; Enable for checking of key release.
BSET OCIE,TCR

EXIT_COMP
CLR PORTA
RTS
*==================================================================
* DELAY OF 100 MS
*==================================================================
DELAY_100MS
LDX #!112
LOAD_ACC
LDA #$FF
DECR DECA
BNE DECR
DECX
BNE LOAD_ACC
RTS
*************************************************************************
* INTERRUPT SERVICE ROUTINES.
*************************************************************************
* KEYBOARD INTERRUPT ROUTINE

KBDISR BCLR KEYF,MISC
BRSET CHK_KEY_REL,USRCNT2,NO_KEY; No key switch recognition
; till none of the keys are depressed.
BRSET NO_KEY_PROCESS,STATUS_FLAG,NO_KEY; Prevent key processing until
; the new call display is over.
BSET KEY_INT_SENSED,TASK_REQUEST1; Set flag to find the key.
BSET PENDING_TASK,USRCNT1; Set flag for task processing.
NO_KEY RTI

*=====================================================================
* IRQISR EXTERNAL INTERRUPT SUBROUTINE

IRQISR BRSET SET_SIX_SEC,USRCNT1,CHK_INT2; Check if the ring is already
; received and carrier detect is awaited.

BRCLR INTF1,MISC,EXIT_INT; Check if it was a ring detect interrupt.
BCLR INTF1,MISC ; Clear the flag bit.
BCLR INTE1,EVNEN ; Disable the ring detect interrupt for.
; eight seconds.
CLR PWR_ON_CNTR
BCLR RING_DETECT,STATUS_FLAG
BSET CHK_VALID_RING,USRCNT2; Set the flag to wait for a valid
; ring input.
BCLR INTF2,MISC
BSET INTN2,SYSR ; Select active low signal interupt.
BSET INTE2,EVNEN ; Enable the carrier detect interrupt.

CHK_INT2
BRCLR INTF2,MISC,EXIT_INT; Check if it was a carrier detect int.
BCLR INTF2,MISC ; Clear the flag bit.
BCLR INTE2,EVNEN ; Disable the carrier detect interrupt.
BRCLR RING_DETECT,STATUS_FLAG,EXIT_INT; Valid ring was not detected
; if the flag is clear.
BCLR RING_DETECT,STATUS_FLAG; Clear the ring detect flag.
BCLR SET_ONE_SEC,USRCNT1; Clear one second timeout flag.
CLR PWR_ON_CNTR
BSET SET_HALF_SEC,USRCNT1; Set timeout of 1/2 sec for data reception.
BSET ICIE,TCR ; Enable the timer capture interrupt to detect
; the cooked data input.
CLR BIT_COUNTER ; Clear the variables used in the data
CLR BYTE_COUNTER ; collection process.
CLR CHECK_SUM
CLR POINTER

LDA USRCNT1 ; Clear the SDMF,MDMF,TAKE_CHECKSUM bits
AND #%11111000 ; in the USRCNT1 register.
STA USRCNT1

EXIT_INT RTI

************************************************************************
* TIMER INTERRUPT
TMISR BRCLR TOF,TSR,OUTPUT_COMPARE; Check for tof flag of tsr
LDA TCRL

BRCLR SET_SIX_SEC,USRCNT1,FIVE_SEC;Chk if ring detect enable
; time out has been set.
LDA TIME_OUT_COUNTER ; Count six seconds before enabling
CMP #!5 ; ring detect interrupt.
BNE NO_CARR_TIME
CLR TIME_OUT_COUNTER
BRSET RDO,PORTD,ENABLE_RING; Poll for ring line. Enable the
BCLR INTF1,MISC ; ring interrupt when the ring
BRA NO_CARR_TIME ; line goes high.
ENABLE_RING
BCLR SET_SIX_SEC,USRCNT1
BCLR INTF1,MISC
BSET INTE1,EVNEN ; Enable the ring detect interrupt .
BCLR DONT_STOP,STATUS_FLAG ; Enable for entering stop mode.
BRA FIVE_SEC

NO_CARR_TIME
INC TIME_OUT_COUNTER ; Increment the time out counter for
; timing out the ring enable or carrier
; detect.
FIVE_SEC
BRCLR SET_FIVE_SEC,USRCNT1,EXIT_; check if FIVE seconds
INC FIVESEC_COUNT ; counter has to be incremented.
LDA FIVESEC_COUNT
CMP #$05
BNE EXIT_
CLR FIVESEC_COUNT
BSET FIVE_SEC_OVER,STATUS_FLAG; Set the FIVE seconds expiry flag .
BSET PENDING_TASK,USRCNT1 ; Set task execution request bit.
EXIT_ JMP EXIT_TMR
*=====================================================================
* OUTPUT_COMPARE
* sets the output compare interrupt time for 100ms.

OUTPUT_COMPARE
BRSET OCF,TSR,OCOM_INT; Reading TSR and output compare low
; register enables the next tcmp int.
JMP CHK_INCAP
OCOM_INT
LDA OCRL
JSR RELOAD_TIMER
BRCLR CHK_VALID_RING,USRCNT2,RING_RECD; Check if RDO has to be
; polled.
INC PWR_ON_CNTR ; Wait for 300 milliseconds to
LDA PWR_ON_CNTR ; CHECK FOR RDO.
CMP #$3
BNE EXIT_TMR
BCLR CHK_VALID_RING,USRCNT2; Clear the ring signal polling flag.
BRCLR RDO,PORTD,VALID_RING; If the RDO pin is set, there is no
; ring.
BCLR INTF1,MISC ; Clear the flag bit.
BSET INTE1,EVNEN ; Enable the ring detect interrupt.
BCLR DONT_STOP,STATUS_FLAG; Clear the flag to enter stop mode.
BRA DISABLE_CAR_INT ; Disable carrier detect interrupt.

VALID_RING
BRCLR RDO,PORTD,VALID_RING; Wait till the ring ling goes high.
BSET RING_DETECT,STATUS_FLAG; Set flag to accept carrier detect .
BCLR CLID_CHIP_PWR,PORTD; Power on the CLID IC 145447.
CLR TIME_OUT_COUNTER
BSET SET_SIX_SEC,USRCNT1; Set flag to enable six seconds
; time out count.
CLR PWR_ON_CNTR
BSET SET_ONE_SEC,USRCNT1; Set one second timeout flag for carrier
; detect.
BSET TOIE,TCR ; Enable timer overflow int.
BRA EXIT_TMR

RING_RECD
BRCLR SET_ONE_SEC,USRCNT1,CHK_HALF_SEC; Check if one second
INC PWR_ON_CNTR ; waiting period for data reception
LDA PWR_ON_CNTR ; is enabled. if yes even after
CMP #$0A ; one second of non reception of
BNE EXIT_TMR ; data,
BSET CLID_CHIP_PWR,PORTD ; Power off the CLID IC 145447.
BCLR SET_ONE_SEC,USRCNT1
BCLR RING_DETECT,STATUS_FLAG ; Clear the ring detect flag.
DISABLE_CAR_INT
BCLR INTF2,MISC ; Clear the carrier int flag bit.
BSET INTE2,EVNEN ; Disable the carrier detect interrupt.
BRA KEY_RELEASED

CHK_HALF_SEC
BRCLR SET_HALF_SEC,USRCNT1,NO_CLID_PWR; Check if waiting period
INC PWR_ON_CNTR ; for data reception is enabled.
LDA PWR_ON_CNTR ; timeout for 1/2 second for data.
CMP #$05 ; If data is not received even after
BNE EXIT_TMR ; half second,
BSET CLID_CHIP_PWR,PORTD ; Power off the CLID IC 145447.
BCLR SET_HALF_SEC,USRCNT1
BRA KEY_RELEASED
NO_CLID_PWR
BRSET NO_KEY_PROCESS,STATUS_FLAG,CHK_FLASH
BRCLR CHK_KEY_REL,USRCNT2,KEY_RELEASED
LDA PORTA ; Test if any of the keys are still
AND #%00001100 ; depressed.
CMP #$0C ; Check for key release.
BEQ KEY_RELEASED
BRA CHK_FLASH

KEY_RELEASED
BCLR OCIE,TCR ; Disable output compare interrupt.
BCLR NO_KEY_PROCESS,STATUS_FLAG
BCLR KEYF,MISC ; Clear key interrupt flag.
BCLR CHK_KEY_REL,USRCNT2
CHK_FLASH
BRCLR SET_DISP_FLASH,USRCNT2,EXIT_TMR; Check if display flash is
BSET OCIE,TCR ; required.Enable output compare int.
INC FLASH_COUNT ; Update the display every 400ms.
LDA FLASH_COUNT
CMP #$4
BNE EXIT_TMR
CLR FLASH_COUNT
BSET FLASH_DISP,USRCNT2 ; Set the bit to execute the task.

EXIT_TMR RTI

*=========================================================================
CHK_INCAP
BRCLR ICF,TSR,EXIT_INCAP; Reading TSR and input capture low
LDA ICRL ; register enables the next tcmp int.
MUL ; Dummy instructions for some delay.
MUL
MUL
MUL
BRSET COOK_DATA,PORTD,NOT_A_START
BCLR SET_HALF_SEC,USRCNT1; Clear the half second time out for
; data reception.
BCLR ICIE,TCR ; Disable the input capture interrupt.
BCLR OCIE,TCR ; Disable output compare interrupt.
JSR HALF_BAUD_DELAY

WAIT_FOR_START
BRCLR COOK_DATA,PORTD,START_BIT_RECD; Wait for the start bit to be
BRA NOT_A_START ; received before proceeding to collect data.

START_BIT_RECD
JSR BAUD_DELAY ; Give a delay of approx 833us.
BRSET COOK_DATA,PORTD,DATA1
DATA0 CLC ; Carry = 0; i.e. received bit is 0
BRA STDATA
DATA1 SEC ; Carry = 1; i.e. received bit is 1

STDATA ROR DATA ; Store received bit into data.
INC BIT_COUNTER
LDA BIT_COUNTER ; Collect 8bits for a data byte.
CMP #08
BNE START_BIT_RECD
CLR BIT_COUNTER

JSR BAUD_DELAY
BRSET COOK_DATA,PORTD,RECEIVED_STOP_BIT;Check for the stop bit.
BRA NO_DATA_STORE ; Stop bit not received.
*----------------------------------------------------------------------
RECEIVED_STOP_BIT
INC BYTE_COUNTER
BSET ICIE,TCR ; Enable the input capture interrupt.

BRSET TAKE_CHECKSUM,USRCNT1,COMPARE_CHECKSUM; Check if the
; data byte is the checksum.
LDA BYTE_COUNTER ; Check to see if the data stream that is
CMP #$01 ; to be received is single or multiple
BNE STORE_BYTE ; data message format.

LDA DATA
CMP #$04 ; Value 04 corresponds to single data format.
BNE MULTI_DATA
BSET SDMF_DATA,USRCNT1; Set the single data message format flag.
BRA CAL_CHECKSUM
MULTI_DATA
; BSET MDMF_DATA,USRCNT1; Set the multiple data message format flag.
; BRA CAL_CHECKSUM
BRA NO_DATA_STORE ; Multi data format is not included.

*---------------------------------------------------------------------
STORE_BYTE
BRCLR SDMF_DATA,USRCNT1,MULTI_
JSR SINGLE_DATA ; Collect the data in a temp buffer.
BRA CAL_CHECKSUM
MULTI_ ;JSR MULTIPLE_DATA
BRA NO_DATA_STORE ; Multi data format is not included.
CAL_CHECKSUM
LDA DATA ; Add all the bytes for calculating
ADD CHECK_SUM ; the checksum.
STA CHECK_SUM
BRA EXIT_INCAP

COMPARE_CHECKSUM
COM CHECK_SUM ; Get the 2's complement
INC CHECK_SUM
LDA DATA ; Compare the received checksum with
CMP CHECK_SUM ; the stored one.
BNE NO_DATA_STORE

BSET DISP_NEW_CALL,TASK_REQUEST1; Set the flag to start data storage
BSET PENDING_TASK,USRCNT1
BRA PWR_OFF
NO_DATA_STORE
BCLR NO_KEY_PROCESS,STATUS_FLAG
PWR_OFF
BCLR TAKE_CHECKSUM,USRCNT1; Clear flag to accept checksum data.
BSET CLID_CHIP_PWR,PORTD ; Remove the power signal to clid chip.
BCLR OCIE,TCR ; Disable the output compare int.
DONT_SET_INT BCLR ICIE,TCR ; Disable the input capture int.
EXIT_INCAP
NOT_A_START RTI
*===================================================================
RELOAD_TIMER
* Load the output compare registers with value 15D8H to generate
* an O/P compare interrupt for every 100ms.

LDX ACRH ; Load high byte of counter.
LDA ACRL ; Load low byte of counter.
ADD #$D8 ; Add low byte with the value D8h.
STA TEMP ; Store low byte result temporarily.
TXA ; Transfer high byte of counter to accumulator
ADC #$15 ; Add high byte with 15h.
TAX ; Transfer high byte result to x register.
LDA TEMP ; Load low byte result from temp.
STX OCRH ; Store high byte of output compare register.
LDX TSR ; Clear output compare flag.
STA OCRL ; Store low byte of output compare register.
RTS
*======================================================================

* Delay of approximately 790us

HALF_BAUD_DELAY
LDA #!67;
BRA DECREMENT
BAUD_DELAY
LDA #!180
DECREMENT
NOP ; 2
DECA ; 3
BNE DECREMENT ; 3
RTS
*=======================================================================
SINGLE_DATA
LDA BYTE_COUNTER ; Test if the data received corresponds to
CMP #$02 ; the message length info.
BNE NOT_LENGTH
LDA DATA
STA MESSAGE_LENGTH
RTS
NOT_LENGTH
LDA DATA
LDX POINTER
STA TEMP_DATA_BUFFER,X; Store the values into a temporary buffer
INC POINTER
LDA POINTER
CMP #!08 ; Check if the date and time data bytes
BNE COMPARE_LAST ; are already stored.
LDA MESSAGE_LENGTH ; Check if the message length is 9.If yes
CMP #$0A ; don't tamper.
BLO DATA_NOT_FULL ;
LDA #!18 ; Check if the message length is 18.If yes
SUB MESSAGE_LENGTH ; don't tamper. Else if the message length
BEQ DATA_NOT_FULL ; is inbetween 9 and 18, fill ascii blank
STA COUNT ; in the data area and increase message length
LDA #$20 ; count till it is 18.
REFILL
LDX POINTER
STA TEMP_DATA_BUFFER,X; Store the values into a temporary buffer
INC POINTER
INC MESSAGE_LENGTH
DEC COUNT
BNE REFILL
COMPARE_LAST
CMP MESSAGE_LENGTH ; Check if all the data bytes have been recd.
BNE DATA_NOT_FULL
BSET TAKE_CHECKSUM,USRCNT1; Set flag to accept checksum data.
DATA_NOT_FULL
RTS
*=====================================================================
PUT_BAT_LOW
CLRX
NEXT_CHAR
LDA LOW_BATTERY,X ; Read the ASCII table containing the values
CMP #'*' ; required for displaying the logo.
BEQ CH_OVER5 ; Write the data to the display.
STX TEMPX
JSR FILL_DATA
LDX TEMPX
INCX
BRA NEXT_CHAR
CH_OVER5 LDA #$05 ; Beep buzzer five times.
STA COUNT

************************************************************************
CRYSTAL_LOGO
FCB ' CRYSTAL*'
CALL_LOGO
FCB ' 25 CALLS*'
NO_CALL
FCB ' NO CALLS *'
PAY_PH
FCB ' PAY PHONE*'
OUT_PH
FCB ' OUT OF AREA*'
LOW_BATTERY
FCB ' BATT LOW!! *'
DATA_ERROR
FCB 'DATA ERROR*'
LAST_CALL_DELETE
FCB 'LAST CALL DELETE*'
NO_SPACE
FCB ' FULL*'
*=================================================================
* KEYPAD LOOKUP TABLE *
KEYTBL
FCB %00011000,$04 ; DELETE
FCB %00101000,$02 ; LOCK
FCB %00100100,$08 ; REVIEW REV
FCB %00010100,$01 ; REVIEW_FF
******************************************************************
SPIISR
SW_INT RTI
******************************************************************

ORG $1FFE ; RESET VECTOR
FDB INIT

ORG $1FFA ; EXTERNAL INTERRUPT (IRQ) VECTOR
FDB IRQISR

ORG $1FF6 ; TIMER INTERRUPT VECTOR (ICF,OCF,TOF)
FDB TMISR

ORG $1FF8 ; KEYBOARD INTERRUPT VECTOR
FDB KBDISR

ORG $1FFC
FDB SW_INT ; SOFTWARE INTERRUPT

ORG $1FF4 ; SPI INTERRUPT VECTOR
FDB SPIISR
*****************************************************************
* END
 

 

Hosted by www.Geocities.ws

1