;Contacts database selected so put it on screen and check for button push cdbmenu: clr cursorow ldi ZL,low(contacts) ;load contacts start address ldi ZH,high(contacts) rcall dispcontact ;display first contact info ldi wreg,0b00001110 ;display cursor rcall lcdcmd ldi wreg,0x80 rcall lcdcmd ldi temp,1 ;keep track of which contact # we're on mov tempsave,temp cdblp: sbic PINB,6 ;check left button rjmp cdbbut7 ;if not pushed check 2nd button ldi wreg,64 rcall debounce ;if pushed debounce it tst flag breq cdblp ;if not proper push, continue looping ldi timeout,2 ;get 2 iterations in loop ldi temp,1 cp tempsave,temp breq wbut6 dec tempsave cdbflp: ldi XL,low(contacts) ;check to make sure not at first contact yet ldi XH,high(contacts) cp XL,ZL cpc XH,ZH breq cdbendc sbiw ZL,1 ;go back 2 contact terminators and forward ld wreg,Z ; by one char for contact before current one cpi wreg,0x03 brne cdbflp dec timeout brne cdbflp ;once back 2 contact terminators adiw ZL,1 ;move forward to first character of contact cdbendc:rcall dispcontact ;display the contact ldi wreg,0x80 rcall lcdcmd wbut6: sbis PINB,6 rjmp wbut6 rjmp cdblp ;continue checking buttons cdbbut7:sbic PINB,7 ;check right button rjmp cdbbut1 ;if not pushed loop again ldi wreg,128 rcall debounce ;if pushed debounce it tst flag breq cdblp ;if not proper push, continue looping cp tempsave,cdbcount breq cdblp ;if already at rightmost contact keep looping inc tempsave adiw ZL,1 ;move forward to first character of contact rcall dispcontact ;display the contact ldi wreg,0x80 rcall lcdcmd wbut7: sbis PINB,7 rjmp wbut7 rjmp cdblp ;continue checking buttons cdbbut1:sbic PINB,1 ;check add button rjmp cdbbut2 ;if not pushed loop again ldi wreg,2 rcall debounce ;if pushed debounce it tst flag breq cdblp ;if not proper push, continue looping ldi wreg,contactlimit ;limit the number of contacts to 2 to fit in 8535 SRAM cp cdbcount,wreg breq cdbbut2 ;so if we're at the limit don't allow another addition inc cdbcount ;there's now going to be another contact wbut1: sbis PINB,1 ;wait for button release rjmp wbut1 ldi ZL,low(contacts) ldi ZH,high(contacts) rcall cdbadd ;add new blank contact rjmp cdbmenu ;display the new blank first contact cdbbut2:sbic PINB,2 ;check delete button rjmp cdbbut3 ;if not pushed loop again ldi wreg,4 rcall debounce ;if pushed debounce it tst flag breq cdbbut2 ;if not proper push, continue looping dec cdbcount wbut2: sbis PINB,2 rjmp wbut2 rcall cdbdel ldi temp,0 cp cdbcount,temp breq noconts rjmp cdbmenu ;there are contacts remaining so display the first one noconts:ldi wreg,0b00001100 rcall lcdcmd rjmp cmmenu ;return to cmmenu because there's nothing to display cdbbut3:sbic PINB,3 ;check to see if the user wants to edit the current rjmp cdbbut4 ; line ldi wreg,16 rcall debounce ;debounce tst flag breq cdbret wbut3: sbis PINB,3 ;wait for button to be released rjmp wbut3 rcall cdbedit ;call edit subroutine to handle it cdbret: rjmp cdblp cdbbut4:sbic PINB,4 ;check to see if the user wants to move to the previous rjmp cdbbut5 ; line ldi wreg,32 rcall debounce ;debounce tst flag breq cdblp1 wbut4: sbis PINB,4 ;wait for button to be released rjmp wbut4 cpi cursorow,0 ;idetify what row we are presently on breq row41 cpi cursorow,1 breq row42 cpi cursorow,2 breq row43 ldi wreg,0x94 ;if we are on row 4 move to row 3 rcall lcdcmd dec cursorow cdblp1: rjmp cdblp row41: rjmp cdblp ;if on row one do nothing row42: dec cursorow ;if on row 2 move to row 1 ldi wreg,0x80 rcall lcdcmd rjmp cdblp row43: dec cursorow ;if on row 3 move to row 2 ldi wreg,0xC0 rcall lcdcmd rjmp cdblp cdbbut5:sbic PINB,5 ;check to see if the user wants to move down one rjmp cdbbut0 ; line ldi wreg,64 rcall debounce ;debounce tst flag breq cdblp1 wbut5: sbis PINB,5 ;wait for button to be released rjmp wbut5 cpi cursorow,0 ;identify what row we are presently on breq row51 cpi cursorow,1 breq row52 cpi cursorow,2 breq row53 rjmp cdblp ;if on row 4 do nothing row51: inc cursorow ;if on row one move to row 2 ldi wreg,0xC0 rcall lcdcmd rjmp cdblp row52: inc cursorow ;if on row 2 move to row 3 ldi wreg,0x94 rcall lcdcmd rjmp cdblp row53: inc cursorow ;if on row 3 move to row 4 ldi wreg,0xD4 rcall lcdcmd rjmp cdblp cdbbut0:sbic PINB,0 ;check to see if the user if ready to exit rjmp cdblp ldi wreg,1 rcall debounce ;debounce tst flag breq cdblp1 wbut0: sbis PINB,0 ;wait for button to be released rjmp wbut0 rjmp cmmenu ;jump back to menu ;displays 4 lines of contact information at the addr passed in on Z dispcontact: ldi temp,2 ;2 count to put first and last name on same line ldi YL,low(row1) ;load addr for first display row ldi YH,high(row1) cdbr1: ld wreg,Z ;load in character adiw ZL,1 cpi wreg,0x03 ;check for end of current contact breq cdbr1 ;if not keep going cpi wreg,0x01 ;check for end of contact data breq cdbfin ; rjmp cdbr1 ;if not done with all contacts keep going skipck1:cpi wreg,0x02 ;check for end of current field brne skipdec ;if so skip decrement dec temp ;if so decrement field data count breq cdb2 ;check for end of current line data rjmp cdbr1 ;if not done keep looping skipdec:st Y,wreg ;store data in RAM to be displayed adiw YL,1 rjmp cdbr1 cdb2: ldi temp,0x00 ;store terminating 0x00 st Y,temp ldi YL,low(row2) ;load addr for 2nd display row ldi YH,high(row2) cdbr2: ld wreg,Z ;load in character adiw ZL,1 cpi wreg,0x03 ;check for end of current contact breq cdbr2 ;if not keep going cpi wreg,0x01 ;check for end of contact data breq cdbfin skipck2:cpi wreg,0x02 ;check for end of current field breq cdb3 st Y,wreg ;store data in RAM to be displayed adiw YL,1 rjmp cdbr2 cdb3: ldi temp,0x00 ;store terminating 0x00 st Y,temp ldi YL,low(row3) ;load addr for 3rd display row ldi YH,high(row3) cdbr3: ld wreg,Z ;load in character adiw ZL,1 cpi wreg,0x03 ;check for end of current contact breq cdbr3 ;if not keep going cpi wreg,0x01 ;check for end of contact data breq cdbfin skipck3:cpi wreg,0x02 ;check for end of current field breq cdb4 st Y,wreg ;store data in RAM to be displayed adiw YL,1 rjmp cdbr3 cdb4: ldi temp,0x00 ;store terminating 0x00 st Y,temp ldi YL,low(row4) ;load addr for 4th display row ldi YH,high(row4) cdbr4: ld wreg,Z ;load in character adiw ZL,1 cpi wreg,0x03 ;check for end of current contact breq cdbr4 ;if not keep going cpi wreg,0x01 ;check for end of contact data breq cdbfin skipck4:cpi wreg,0x02 ;check for end of current field breq cdbfin1 ;check for end of current line data skipdec2:st Y,wreg ;store data in RAM to be displayed adiw YL,1 rjmp cdbr4 cdbfin1:ldi temp,0x00 ;store terminating 0x00 st Y,temp cdbfin: rcall print4lines ;this writes back the data altered in edit mode from the display RAM to db RAM cdbback:ldi XL,low(contacts);catch the case where it's the first contact ldi XH,high(contacts) cp ZL,XL cpc ZH,XH breq cdcont sbiw ZL,1 ;move back to last contact ld temp,Z cpi temp,0x03 ;by checking for terminator string brne cdbback adiw ZL,1 ;then move forward one to start of string cdcont: ldi YL,low(row1) ;set up pointer to rows ldi YH,high(row1) ldi timeout,10 ;copy first name from row to contacts db RAM cdbfnlp:ld temp,Y ;load data from display row adiw YL,1 ;prepare for next character st Z+,temp ;store data to contact dec timeout brne cdbfnlp ;repeat until first name done ldi temp,0x02 ;add field terminator st Z+,temp ldi timeout,10 ;now copy last name cdblnlp:ld temp,Y adiw YL,1 ;prepare for next character st Z+,temp ;store data to contact dec timeout brne cdblnlp ;repeat until last name done ldi temp,0x02 ;add field terminator st Z+,temp ldi timeout,20 ;now copy addr1 ldi YL,low(row2) ;set up pointer to row ldi YH,high(row2) cdbadd1:ld temp,Y adiw YL,1 ;prepare for next character st Z+,temp ;store data to contact dec timeout brne cdbadd1 ;repeat until addr1 done ldi temp,0x02 ;add field terminator st Z+,temp ldi timeout,20 ;now copy addr2 ldi YL,low(row3) ;set up pointer to row ldi YH,high(row3) cdbadd2:ld temp,Y adiw YL,1 ;prepare for next character st Z+,temp ;store data to contact dec timeout brne cdbadd2 ;repeat until addr2 done ldi temp,0x02 ;add field terminator st Z+,temp ldi timeout,10 ;now copy phone number ldi YL,low(row4) ;set up pointer to row ldi YH,high(row4) cdbpnum:ld temp,Y adiw YL,1 ;prepare for next character st Z+,temp ;store data to contact dec timeout brne cdbpnum ;repeat until phone number is done ldi temp,0x02 ;add field terminator st Z+,temp ldi temp,0x03 ;add contact terminator st Z,temp ret ;this will add a contact entry to the beginning of the list (Java takes ; care of the sorting later when they're written back) ; it is done by moving each contact forward by one entry then taking ; the entered data and placing in the new slot at the front of the list cdbadd: ldi YL,low(contacts);Y marks first slot in list ldi YH,high(contacts) ld temp,Z cpi temp,0x01 brne cdbad1 mov XL,YL mov XH,YH adiw ZL,50 ;move Z one contact forward of X adiw ZL,25 st Z+,temp rjmp skipempty cdbad1: ld temp,Z ;first we must find end of list cpi temp,0x01 breq cdbago ;loop until reaching list terminator adiw ZL,1 rjmp cdbad1 cdbago: mov XL,ZL ;set X to Z position mov XH,ZH sbiw XL,1 ;move back to end of last contact adiw ZL,50 ;move Z one contact forward of X adiw ZL,26 ldi temp,0x01 ;place terminator at end of list again st Z,temp sbiw ZL,1 ld temp,X ;store the 0x03 terminator first then run through st Z,temp ; all characters until reaching the very beginning cdbalp: sbiw ZL,1 ;move on to the next character sbiw XL,1 ld temp,X ;move the character if not st Z,temp cp XL,YL ;check to see if at beginning of list yet cpc XH,YH brne cdbalp ;if so we're done creating a contact slot skipempty: ldi temp,0x20 ;now load the space character and blank out mov tempsave,temp ; all of the characters in the new slot ldi temp,0x02 ; while sticking in the proper line terminators of 0x02 ldi timeout,10 ;run through 10 characters first which is the first name cdbafn: st X,tempsave ;store the " " character adiw XL,1 ;move to next character slot dec timeout brne cdbafn ;loop for 10 character slots st X,temp ;store the 0x02 terminator adiw XL,1 ldi timeout,10 ;run through 10 characters for last name cdbaln: st X,tempsave ;store the " " character adiw XL,1 ;move to next character slot dec timeout brne cdbaln ;loop for 10 character slots st X,temp ;store string terminator of 0x02 adiw XL,1 ldi timeout,20 ;run through 20 characters for address line 1 cdbaad1:st X,tempsave ;store the " " character adiw XL,1 ;move to next character slot dec timeout brne cdbaad1 ;loop for 20 character slots st X,temp ;store string terminator of 0x02 adiw XL,1 ldi timeout,20 ;run through 20 characters for address line 2 cdbaad2:st X,tempsave ;store the " " character adiw XL,1 ;move to next character slot dec timeout brne cdbaad2 ;loop for 20 character slots st X,temp ;store string terminator of 0x02 adiw XL,1 ldi timeout,10 ;run through 10 characters for phone number cdbaph: st X,tempsave ;store the " " character adiw XL,1 ;move to next character slot dec timeout brne cdbaph ;loop for 20 character slots st X,temp ;store string terminator of 0x02 adiw XL,1 ldi temp,0x03 st X,temp ;store string terminator of 0x03 ldi ZL,low(contacts) ;move Z to first contacts char to ldi ZH,high(contacts) ; prepare for new blank contact display rcall dispcontact ret ;this will delete the current contact in view by moving ; all of the contacts after it back one contact cdbdel: ldi XL,low(contacts);catch the case where it's the first contact ldi XH,high(contacts) cdbdel2:cp ZL,XL cpc ZH,XH breq cdbdel1 ;we're at the beginning sbiw ZL,1 ;move back to last contact ld temp,Z cpi temp,0x03 ;by checking for terminator string brne cdbdel2 adiw ZL,1 ;then move forward one to start of string mov XL,ZL mov XH,ZH cdbdel1: adiw XL,50 ;move X out one contact ahead of Z adiw XL,26 ld temp,X ;check whether we're at last contact in list cpi temp,0x01 brne cdbmvlp ;if not proceed normally st Z,temp ;otherwise store the 0x01 to mark the end of the list and leave ret cdbmvlp:ld temp,X ;copy each character from next contact to this one st Z,temp adiw ZL,1 ;increment each one to copy next character adiw XL,1 ld temp,X cpi temp,0x01 ;end copying at contacts db terminator brne cdbmvlp st Z,temp ret ;this allows you to edit the current line selected and ; it writes the data back from display RAM to db RAM on exit cdbedit:cpi cursorow,3 ;determine what row we are presently on breq nextrow4 cpi cursorow,2 breq nextrow3 cpi cursorow,1 breq nextrow2 ldi XL,low(row1) ;if on row one load row1 ldi XH,high(row1) ldi wreg,19 ;set line limit to 20 characters rjmp controw nextrow2: ldi XL,low(row2) ;if on row 2 load row2 ldi XH,high(row2) ldi wreg,19 ;set line limit to 20 characters rjmp controw nextrow3: ldi XL,low(row3) ;if on row 3 load row 3 ldi XH,high(row3) ldi wreg,19 ;set line limit to 20 characters rjmp controw nextrow4: ldi XL,low(row4) ;if on row 4 load row4 ldi XH,high(row4) ldi wreg,9 ;set line limit to 10 characters rjmp controw controw: mov YL,XL ;load pointers for Editchar subroutine mov YH,XH rcall Editchar ;call subroutine to handle editting ;pin3 gets you into editing and after pin0 enter you come back here rcall cdbback ;write updated display back to memory ldi wreg,0b00001110 ;display cursor rcall lcdcmd ldi wreg,0x80 ;reset cursor to the beginning rcall lcdcmd ret ;return