;****************** ;Kentucky Department for the Blind ;427 Versailles Road ;Frankfort, Ky 40601 ;502-573-4754 ;Wayne D. Thompson, P.E. ;February 25, 1992 ;This software is for the braille digital clock/calendar ;designed by the Kentucky Department for the Blind. ;File -- \drawing\brlclock\clock.asm ;Version 1.0 -- 12-2-92 ;Basic operation -- The 8749 single chip microcomputer is ;interrupted once each second by the Dallas DS1287 Real Time ;Clock chip. During each interrupt this program reads the ;time and updates the Tiflotel 500/N6/PZ 6-cell piezoelectric ;braille display. Also, the program checks for alarm condition ;and constantly monitors the user switches for mode changes and ;other user commands. ;NOTE: All code related to the stopwatch feature is for ;possible future implementation and is currently incomplete. pl 59 ;(set page length for list file) ;****************** ;8749 register assignments ;register bank 0 ;R7 -- general purpose use ;R6 -- general purpose use ;R5 -- general purpose use ;R4 -- general purpose use ;R3 -- general purpose use ;R2 -- general purpose use ;R1 -- RAM pointer ;R0 -- RAM pointer ;register bank 1 (used only during interrupts) ;R7 -- general purpose use ;R6 -- ;R5 -- ;R4 -- ;R3 -- ;R2 -- save accum here on interrupt ;R1 -- RAM pointer to clock chip register copies ;R0 -- RAM pointer to clock chip registers ;****************** ;8749 RAM data upper memory map (32 bytes, volatile) BRLDAT equ 20h ;1st of 6 bytes of data for braille ;display, cells 1 thru 6 CMODE equ 26h ;current Mode ;(one high bit indicates selection) ;bit 0 = View Mode ;bit 1 = Set Mode CFUNCTION equ 27h ;current Function ;(one high bit indicates selection) ;bit 0 = Time Function ;bit 1 = Alarm Function ;bit 2 = Date Function ;bit 3 = Stopwatch Function (not ; implemented) CSELECT equ 28h ;current cell or item to "Set" ;(one high bit indicates selection) ;bit 0 thru 5 = cells 1 thru 6 ;bit 6 = am/pm ; (or stopwatch count up/down) ;bit 7 = alarm enabled/disabled ; (or stopwatch auto retime on/off) ;no high bits = weekday SWHOUR equ 29h ;stopwatch hour value (BCD 0-99) SWMIN equ 30h ;stopwatch minute value (BCD 0-59) SWSEC equ 31h ;stopwatch second value (BCD 0-59) ;****************** ;8749 I/O port assignments ;P10 -- output to Tiflotel's "data in" input ;P11 -- output to Tiflotel's "clock" input ;P12 -- output to Tiflotel's "strobe" input ;P13 -- spare ;P14 -- spare ;P15 -- spare ;P16 -- spare ;P17 -- spare ;P20 -- output to audio indicator for alarm (0=alarm sounding) ;P21 -- spare ;P22 -- spare ;P23 -- spare ;Lines P24-P27 are inputs from user pushbuttons and are ;coded 0=pressed, 1=not pressed. ;P24 -- CHANGE switch (increments thru values; reset stopwatch) ;P26 -- SELECT switch (toggles hours/min/sec or ; month/day/year; am/pm; alarm on/off) ;P26 -- FUNCTION switch (toggles time/alarm/date/stopswatch) ;P27 -- MODE switch (toggles view/set) ;T0 -- spare ;T1 -- spare ;****************** ;DS1287 Clock Chip memory map (64 bytes total, non-volatile) ;these first 14 location 0-0dh are pre-assigned by Dallas SEC_ equ 00h ;seconds (BCD 00-59) SECA_ equ 01h ;seconds alarm (BCD 00-59) MIN_ equ 02h ;minutes (BCD 00-59) MINA_ equ 03h ;minutes alarm (BCD 00-59) HOUR_ equ 04h ;hours (BCD 01-12am, 81-92pm) HOURA_ equ 05h ;hours alarm (BCD 01-12am, 81-92pm) WKDAY_ equ 06h ;weekday (BCD 01-07, sunday=1) DAY_ equ 07h ;day of month (BCD 01-31) MONTH_ equ 08h ;month (BCD 01-12) YEAR_ equ 09h ;year (BCD 00-99) REGA_ equ 0ah ;control & status register A REGB_ equ 0bh ;control & status register B REGC_ equ 0ch ;control & status register C REGD_ equ 0dh ;control & status register D SPARE1 equ 0eh ;unused SPARE2 equ 0fh ;unused ;These next 14 locations are my copies of the clock's first ;14 locations 0-0dh. These are recopied during the ;interrupt once every second. SEC equ 10h ;seconds (BCD 00-59) SECA equ 11h ;seconds alarm (BCD 00-59) MIN equ 12h ;minutes (BCD 00-59) MINA equ 13h ;minutes alarm (BCD 00-59) HOUR equ 14h ;hours (BCD 01-12am, 81-92pm) HOURA equ 15h ;hours alarm (BCD 01-12am, 81-92pm) WKDAY equ 16h ;weekday (BCD 01-07, sunday=1) DAY equ 17h ;day of month (BCD 01-31) MONTH equ 18h ;month (BCD 01-12) YEAR equ 19h ;year (BCD 00-99) REGA equ 1ah ;control & status register A REGB equ 1bh ;control & status register B REGC equ 1ch ;control & status register C REGD equ 1dh ;control & status register D SPARE3 equ 1eh ;unused SPARE4 equ 1fh ;unused ;****************** ;power on reset org 0 jmp start ;****************** ;Real Time Clock chip interrupt routine. Called once per ;second immediately after each clock chip internal update, ;or, upon alarm condition. Must be out within 999 msec. org 3 int sel rb1 ;use register bank 1 during interrupt mov r2,a ;save accum mov r0,#REGC_ ;determine source of interrupt movx a,@r0 ; by reading register C jb5 int2 ;jump if Alarm caused interrupt jb4 int0 ;jump if Update Ended caused interrupt jmp int9 ;otherwise, abort int0 ;Read & copy all registers from the ; Real Time Clock chip mov r0,#SEC_ ;init RAM pointers mov r1,#SEC mov r7,#14 ;init counter to read all 14 registers int1 movx a,@r0 ;read register contents movx @r1,a ;copy it to my location inc r0 inc r1 djnz r7,int1 ;read next register until done jmp int9 int2 mov r0,#REGB_ ;alarm enabled? movx a,@r0 jb5 int3 ;yes jmp int9 ;no int3 anl p2,#0feh ;sound alarm int9 mov a,r2 ;recover accum sel rb0 retr ;****************** ;Initialize things init mov r0,#REGA_ ;init clock register A mov a,#00100000b movx @r0,a mov r0,#REGB_ ;init clock register B movx a,@r0 ;first, get current alarm status jb5 init1 ;jump if enabled mov a,#00010001b ;keep it disabled jmp init2 init1 mov a,#00110001b ;keep it enabled init2 movx @r0,a orl p2,#0f1h ;set alarm sounding to off mov r0,#CMODE mov @r0,#1 ;set MODE to VIEW mov r0,#CFUNCTION mov @r0,#1 ;set FUNCTION to TIME mov r0,#CSELECT mov @r0,#1 ;set SELECT to cell 1 ret ;****************** ;Enter with message number in accum. ;Send message to braille display. message mov r3,a ;init message pointer page 3 loc mov a,#58 mess0 add a,#6 djnz r3,mess0 mov r4,a ;save start of message pointer mov r1,#BRLDAT ;init buffer pointer mov r2,6 ;init char counter mess1 mov a,r4 ;get char movp3 a,@a mov @r1,a ;put it in buffer inc r1 inc r4 djnz r2,mess1 ;copy remaining chars call bral_it ;send message to braille display ret ;****************** ;wait for all user pushbuttons to be released keyup in a,p2 ;wait for all buttons up cpl a anl a,#0f0h jnz keyup ret ;****************** ;freeze real time clock data copy transfers freeze mov r0,#REGB_ movx a,@r0 orl a,#80h ;disable update transfers movx @r0,a mov r0,#REGB movx @r0,a ;save copy too ret ;****************** ;allow real time clock data copy transfers unfreeze mov r0,#REGB_ movx a,@r0 anl a,#07fh ;enable update transfers orl a,#10h ;re-enable UIE bit 4 movx @r0,a mov r0,#REGB movx @r0,a ;save copy too ret ;***************** ;Load selected item into the braille display buffer and ;send it to the braille display. display mov r0,#CSELECT ;get select setting mov a,@r0 jz dis7 jb6 dis5 jb7 dis6 ;selected item must be cells 1-6 mov r0,#CFUNCTION ;what function is selected? mov a,@r0 jb0 dis0 jb1 dis1 jb2 dis2 jb3 dis3 dis0 jmp d_time ;time dis1 jmp d_alm ;alarm dis2 jmp d_date ;date dis3 jmp d_sw ;stopwatch (not yet implemented) dis5 jmp d_ampm ;am/pm dis6 jmp d_onoff ;on/off dis7 jmp d_wkday ;weekday ;display time items d_time mov r1,#BRLDAT+1 ;init braille buffer pointer mov r0,#HOUR ;get time hours in BCD movx a,@r0 anl a,#0fh add a,#30h ;convert to ASCII mov @r1,a ;save one's digit dec r1 movx a,@r0 anl a,#070h ;strip bits 7 and 0-3 swap a add a,#30h ;convert to ASCII mov @r1,a ;save ten's digit mov r1,#BRLDAT+3 ;init braille buffer pointer mov r0,#MIN ;get time minutes in BCD movx a,@r0 anl a,#0fh add a,#30h ;convert to ASCII mov @r1,a ;save one's digit dec r1 movx a,@r0 anl a,#0f0h ;strip bits 0-3 swap a add a,#30h ;convert to ASCII mov @r1,a ;save ten's digit mov r1,#BRLDAT+5 ;init braille buffer pointer mov r0,#SEC ;get time seconds in BCD movx a,@r0 anl a,#0fh add a,#30h ;convert to ASCII mov @r1,a ;save one's digit dec r1 movx a,@r0 anl a,#0f0h ;strip bits 0-3 swap a add a,#30h ;convert to ASCII mov @r1,a ;save ten's digit jmp d_exit ;display alarm items d_alm mov r1,#BRLDAT+1 ;init braille buffer pointer mov r0,#HOURA ;get alarm hours in BCD movx a,@r0 anl a,#0fh add a,#30h ;convert to ASCII mov @r1,a ;save one's digit dec r1 movx a,@r0 anl a,#070h ;strip bits 7 and 0-3 swap a add a,#30h ;convert to ASCII mov @r1,a ;save ten's digit mov r1,#BRLDAT+3 ;init braille buffer pointer mov r0,#MINA ;get alarm minutes in BCD movx a,@r0 anl a,#0fh add a,#30h ;convert to ASCII mov @r1,a ;save one's digit dec r1 movx a,@r0 anl a,#0f0h ;strip bits 0-3 swap a add a,#30h ;convert to ASCII mov @r1,a ;save ten's digit mov r1,#BRLDAT+5 ;init braille buffer pointer mov r0,#SECA ;get alarm seconds in BCD movx a,@r0 anl a,#0fh add a,#30h ;convert to ASCII mov @r1,a ;save one's digit dec r1 movx a,@r0 anl a,#0f0h ;strip bits 0-3 swap a add a,#30h ;convert to ASCII mov @r1,a ;save ten's digit jmp d_exit ;display date items d_date mov r1,#BRLDAT+1 ;init braille buffer pointer mov r0,#MONTH ;get date month in BCD movx a,@r0 anl a,#0fh add a,#30h ;convert to ASCII mov @r1,a ;save one's digit dec r1 movx a,@r0 anl a,#0f0h ;strip bits 0-3 swap a add a,#30h ;convert to ASCII mov @r1,a ;save ten's digit mov r1,#BRLDAT+3 ;init braille buffer pointer mov r0,#DAY ;get date day in BCD movx a,@r0 anl a,#0fh add a,#30h ;convert to ASCII mov @r1,a ;save one's digit dec r1 movx a,@r0 anl a,#0f0h ;strip bits 0-3 swap a add a,#30h ;convert to ASCII mov @r1,a ;save ten's digit mov r1,#BRLDAT+5 ;init braille buffer pointer mov r0,#YEAR ;get date year in BCD movx a,@r0 anl a,#0fh add a,#30h ;convert to ASCII mov @r1,a ;save one's digit dec r1 movx a,@r0 anl a,#0f0h ;strip bits 0-3 swap a add a,#30h ;convert to ASCII mov @r1,a ;save ten's digit jmp d_exit ;display stopwatch items d_sw mov r1,#BRLDAT+1 ;init braille buffer pointer mov r0,#SWHOUR ;get stopwatch hours in BCD mov a,@r0 anl a,#0fh add a,#30h ;convert to ASCII mov @r1,a ;save one's digit dec r1 mov a,@r0 anl a,#0f0h ;strip bits 0-3 swap a add a,#30h ;convert to ASCII mov @r1,a ;save ten's digit mov r1,#BRLDAT+3 ;init braille buffer pointer mov r0,#SWMIN ;get stopwatch minutes in BCD mov a,@r0 anl a,#0fh add a,#30h ;convert to ASCII mov @r1,a ;save one's digit dec r1 mov a,@r0 anl a,#0f0h ;strip bits 0-3 swap a add a,#30h ;convert to ASCII mov @r1,a ;save ten's digit mov r1,#BRLDAT+5 ;init braille buffer pointer mov r0,#SWSEC ;get stopwatch seconds in BCD mov a,@r0 anl a,#0fh add a,#30h ;convert to ASCII mov @r1,a ;save one's digit dec r1 mov a,@r0 anl a,#0f0h ;strip bits 0-3 swap a add a,#30h ;convert to ASCII mov @r1,a ;save ten's digit jmp d_exit ;display am/pm setting d_ampm mov r0,#CFUNCTION ;time or alarm function? mov a,@r0 jb0 d_ampm3 ;time mov r0,#HOURA jb1 d_ampm4 ;alarm jmp d_ampm5 ;neither d_ampm3 mov r0,#HOUR ;am or pm? d_ampm4 movx a,@r0 jb7 d_ampm1 ;jump if pm mov a,#8 ;am jmp d_ampm2 d_ampm1 mov a,#9 ;pm d_ampm2 call message ;display am or pm d_ampm5 jmp d_exit1 ;display weekday name d_wkday mov r0,#WKDAY ;get weekday code 1-7 movx a,@r0 add a,#9 ;adjust to message # call message ;display weekday jmp d_exit1 ;display alarm on/off setting d_onoff mov r0,#REGB ;alarm on or off? movx a,@r0 jb5 d_onoff1 ;jump if on mov a,#18 ;off jmp d_onoff2 d_onoff1 mov a,#17 ;on d_onoff2 call message ;display alarm on or off jmp d_exit1 ;exit d_exit call bral_it ;braille bcd data in buffer d_exit1 ret ;****************** ;Send the six ASCII bytes in the BRLDAT buffer to the 6-cell ;braille display. bral_it mov r1,#BRLDAT ;init buffer pointer mov r3,#1 ;init for 6 bytes to send (start ; with bit 0 high and shift left) bra3 mov a,@r1 ;get ASCII data call ascbrl ;convert to braille mov r2,a ;save braille char mov r0,#CMODE ;in SET mode? mov a,@r0 jb0 bra5 ;no, jump mov r0,#CSELECT ;yes. This cell SELECTED for SET? mov a,@r0 xrl a,r3 jnz bra5 ;no, jump in a,p2 ;MODE or FUNCTION key down? cpl a jb7 bra5 ;yes, jump jb6 bra5 ;yes, jump mov a,r2 ;no, recover char orl a,#0c0h ;raise bits 6 & 7 (dots 7 & 8) jmp bra4 bra5 mov a,r2 ;recover char bra4 mov r2,#8 bra0 rrc a jc bra1 anl p1,#0feh ;set data bit low jmp bra2 bra1 orl p1,#01h ;set data bit high bra2 orl p1,#02h ;raise clock line to send bit anl p1,#0fdh ;lower clock line djnz r2,bra0 ;send remaining bits inc r1 ;point to next ASCII digit mov a,r3 ;adjust cell counter rl a mov r3,a jb6 bra6 ;jump if done jmp bra3 ;get next cell bra6 ;all bits are now in the braille display orl p1,#04h ;raise strobe line to write all cells anl p1,#0fbh ;lower strobe line ret ;****************** ;Enter with ASCII code (32-95 only) in accum. Exit with ;equivalent braille code in accum. ascbrl mov r2,a ;save ASCII code mov a,#32 ;subtract 32 from ASCII code cpl a ; (form one's complement) add a,#1 ; (form two's complement) add a,r2 ; (add to get difference) movp3 a,@a ;get braille code from TABLE ret ;****************** ;****************** org 300h ;**************************** ;ASCII TO BRAILLE CONVERSION TABLE ;TABLE PAGE 'POSITION + 32' IS THE ASCII DECIMAL CODE FOR ;THE EQUIV BRAILLE TABLE 'VALUE'. ;To get braille code, subtract 32 from the ASCII code and use ;that as pointer into this table. TABLE DB 00H ;#32 SPACE DB 2EH ;#33 ! DB 10H ;#34 " DB 3CH ;#35 # DB 2BH ;#36 $ DB 29H ;#37 % DB 2FH ;#38 & DB 04H ;#39 ' DB 37H ;#40 ( DB 3EH ;#41 ) DB 21H ;#42 * DB 2CH ;#43 + DB 20H ;#44 , DB 24H ;#45 - DB 28H ;#46 . DB 0CH ;#47 / DB 34H ;#48 0 DB 02H ;#49 1 DB 06H ;#50 2 DB 12H ;#51 3 DB 32H ;#52 4 DB 22H ;#53 5 DB 16H ;#54 6 DB 36H ;#55 7 DB 26H ;#56 8 DB 14H ;#57 9 DB 31H ;#58 : DB 30H ;#59 ; DB 23H ;#60 < DB 3FH ;#61 = DB 1CH ;#62 > DB 39H ;#63 ? DB 08H ;#64 @ ` NULL DB 01H ;#65 A a SOH DB 03H ;#66 B b STX DB 09H ;#67 C c ETX DB 19H ;#68 D d EOT DB 11H ;#69 E e ENQ DB 0BH ;#70 F f ACK DB 1BH ;#71 G g BELL DB 13H ;#72 H h BS DB 0AH ;#73 I i HT DB 1AH ;#74 J j LF DB 05H ;#75 K k VT DB 07H ;#76 L l FF DB 0DH ;#77 M m CR DB 1DH ;#78 N n SO DB 15H ;#79 O o SI DB 0FH ;#80 P p DLE DB 1FH ;#81 Q q DC1 DB 17H ;#82 R r DC2 DB 0EH ;#83 S s DC3 DB 1EH ;#84 T t DC4 DB 25H ;#85 U u NAK DB 27H ;#86 V v SYNC DB 3AH ;#87 W w ETB DB 2DH ;#88 X x CAN DB 3DH ;#89 Y y EM DB 35H ;#90 Z z SUB DB 2AH ;#91 [ { ESC DB 33H ;#92 \ | FS DB 3BH ;#93 ] } GS DB 18H ;#94 ^ ~ RS DB 38H ;#95 _ DEL US ;****************** ;ASCII messages for the braille display (6 chars each) view_m db "VIEW " ;message #1 set_m db "SET " ;#2 db " " ;#3 time_m db "TIME " ;#4 alarm_m db "ALARM " ;#5 date_m db "DATE " ;#6 stopw_m db "STOPW " ;#7 am_m db "AM " ;#8 pm_m db "PM " ;#9 sun_m db "SUNDAY" ;#10 mon_m db "MONDAY" ;#11 tue_m db "TUESDA" ;#12 wed_m db "WENSDA" ;#13 thur_m db "THURDA" ;#14 fri_m db "FRIDAY" ;#15 sat_m db "SATDAY" ;#16 alm_on_m db "ALM ON" ;#17 alm_off_m db "ALMOFF" ;#18 ;****************** ;****************** org 400h ;****************** ;main routine start sel rb0 call init en i start0 call display ;send data to the braille display in a,p2 ;watch for first button press cpl a anl a,#0f0h jz start0 jb7 start1 ;MODE button down jb6 start2 ;FUNCTION button down jb5 start3 ;SELECT button down jb4 start4 ;CHANGE button down start1 jmp mode start2 jmp function start3 jmp select start4 jmp change ;****************** ;MODE button is pressed first mode orl p2,#0f1h ;silence alarm (if sounding) mov r0,#CMODE ;get current mode setting mov a,@r0 jb0 mode0 ;view mode selected jb1 mode1 ;set mode selected mode0 mov a,#1 ;load view message pointer jmp mode3 mode1 mov a,#2 ;load set message pointer mode3 call message ;display current mode setting in a,p2 ;wait for all buttons up or cpl a ; CHANGE button down anl a,#0f0h jz mode7 ;jump, all buttons are up jb4 mode4 ;jump, CHANGE button down jmp mode mode4 mov r0,#CMODE ;get current mode setting again mov a,@r0 rl a ;advance to next mode jb2 mode6 ;jump to wrap high bit mov @r0,a ;save new mode mode5 in a,p2 ;wait for CHANGE button up cpl a jb4 mode5 jmp mode mode6 mov @r0,#1 ;wrap advance back to bit 0 jmp mode5 mode7 jmp start0 ;****************** ;FUNCTION button is pressed first function mov r0,#CFUNCTION ;get current function setting mov a,@r0 jb0 fun0 ;time function selected jb1 fun1 ;alarm function selected jb2 fun2 ;date function selected jb3 fun22 ;stopwatch function selected (not ; yet implemented) fun0 mov a,#4 ;load time message pointer jmp fun3 fun1 mov a,#5 ;load alarm message pointer jmp fun3 fun2 mov a,#6 ;load date message pointer jmp fun3 fun22 mov a,#7 ;load stopwatch message pointer fun3 call message ;display current function setting fun7 in a,p2 ;wait for all buttons up or cpl a ; CHANGE button down anl a,#0f0h jz fun8 ;jump, all buttons are up jb4 fun4 ;jump, CHANGE button down jmp fun7 fun4 mov r0,#CFUNCTION ;get current function setting mov a,@r0 rl a ;advance to next function jb3 fun6 ;jump to wrap high bit (change to ; jb4 when stopwatch code is done) mov @r0,a ;save new function fun5 in a,p2 ;wait for CHANGE button up cpl a jb4 fun5 jmp function fun6 mov @r0,#1 ;wrap advance back to bit 0 jmp fun5 fun8 jmp start0 ;****************** ;SELECT button is pressed first ;Action taken depends on which one of the 8 ;combinations of MODE & FUNCTION is currently active. ;SELECT toggles thru all display items for a given ;MODE/FUNCTION setting. In SET MODE a cursor ;(dots 7 & 8) is also displayed under the item ;currently selected. select mov r0,#CMODE ;get current mode setting mov a,@r0 jb0 s0 ;view mode on jb1 s1 ;set mode on s0 mov r0,#CFUNCTION ;get current function setting mov a,@r0 jb0 svt ;view/time jb1 sva ;view/alarm jb2 svd ;view/date jb3 svs ;view/stopwatch s1 mov r0,#CFUNCTION ;get current function setting mov a,@r0 jb0 sst ;set/time jb1 ssa ;set/alarm jb2 ssd ;set/date jb3 sss ;set/stopwatch ;select set/time items sst mov r0,#CSELECT ;get current SELECT value mov a,@r0 ;step to next value jnz sst1 mov a,#1 jmp sst2 sst1 clr c rlc a sst2 mov @r0,a ;save it jmp sel_end ;select view/time items svt mov r0,#CSELECT ;get current SELECT value mov a,@r0 ;step to next value (but jz svt1 ; not each digit of time) jb6 svt2 jb7 svt3 mov a,#40h ;select bit 6 jmp svt4 svt1 mov a,#1 ;select bit 1 jmp svt4 svt2 mov a,#80h ;select bit 7 jmp svt4 svt3 mov a,#0 ;select bit none (weekday) svt4 mov @r0,a ;save it jmp sel_end ;select set/alarm or set/stopwatch ssa sss mov r0,#CSELECT ;get current SELECT value mov a,@r0 ;step to next value rl a mov @r0,a ;save it jmp sel_end ;select view/alarm or view/stopwatch items sva svs mov r0,#CSELECT ;get current SELECT value mov a,@r0 ;step to next value (but jb7 sva1 ; not each digit of time) jb6 sva2 mov a,#40h ;select bit 6 jmp sva3 sva1 mov a,#1 ;select bit 1 jmp sva3 sva2 mov a,#80h ;select bit 7 sva3 mov @r0,a ;save it jmp sel_end ;select view/date or set/date items svd ssd mov r0,#CSELECT ;get current SELECT value mov a,@r0 ;step to next value rl a jb6 ssd1 ssd2 mov @r0,a ;save it jmp sel_end ssd1 mov a,#1 jmp ssd2 ;exit select commands here sel_end call keyup ;wait for SELECT button up jmp start0 ;****************** ;****************** org 500h ;****************** ;CHANGE button is pressed first ;Action taken depends on which one of the 8 ;combinations of MODE & FUNCTION is currently active. change mov r0,#CMODE ;get current mode setting mov a,@r0 jb0 c0 ;view mode on jb1 c1 ;set mode on c0 mov r0,#CFUNCTION ;get current function setting mov a,@r0 jb0 cvt ;view/time jb1 cva ;view/alarm jb2 cvd ;view/date jb3 cvs ;view/stopwatch c1 mov r0,#CFUNCTION ;get current function setting mov a,@r0 jb0 c3 ;set/time jb1 c4 ;set/alarm jb2 c5 ;set/date jb3 c6 ;set/stopwatch c3 jmp cst c4 jmp csa c5 jmp csd c6 jmp css ;silence alarm cvt cva cvd jmp ch_end ;start or stop stopwatch timing cvs ;(code not yet done) jmp ch_end ;***** ;change set/time items cst call freeze in a,p2 ;what item is currently selected? mov r0,#CSELECT mov a,@r0 jb0 cst0 jb1 cst1 jb2 cst2 jb3 cst3 jb4 cst4 jb5 cst5 jb6 cst6 jb7 cst7 jz cst8 cst0 jmp cst_hrs10 ;hours tens digit cst1 jmp cst_hrs1 ;hours ones digit cst2 jmp cst_min10 ;minutes tens digit cst3 jmp cst_min1 ;minutes ones digit cst4 jmp cst_sec10 ;seconds tens digit cst5 jmp cst_sec1 ;seconds ones digit cst6 jmp cst_ampm ;am/pm cst7 jmp cst_alm ;alarm enabled/disabled cst8 jmp cst_weekday ;weekday ;increment hours tens digit cst_hrs10 mov r0,#HOUR_ ;get hours movx a,@r0 add a,#10h ;increment tens digit (upper nibble) jb4 cst_hrs10a ;jump if tens digit is now 1 anl a,#0fh ;otherwise, make it 0 cst_hrs10a movx @r0,a ;save new hours ten's value mov r0,#HOUR movx @r0,a ;save copy too jmp ch_end ;increment hours ones digit cst_hrs1 mov r0,#HOUR_ ;get hours movx a,@r0 add a,#01h ;increment ones digit (lower nibble) mov r7,a ;temp save it anl a,#0fh ;is new value = 10 xrl a,#10 jnz cst_hrs1a ;no mov a,r7 ;yes. change it to 0 anl a,#0f0h mov r7,a cst_hrs1a mov a,r7 ;recover new value movx @r0,a ;save new hours ones value mov r0,#HOUR movx @r0,a ;save copy too jmp ch_end ;increment minutes tens digit cst_min10 mov r0,#MIN_ ;get minutes movx a,@r0 add a,#10h ;increment tens digit (upper nibble) mov r7,a ;temp save it anl a,#0f0h ;is new value = 6 xrl a,#60h jnz cst_min10a ;no mov a,r7 ;yes. change it to 0 anl a,#0fh mov r7,a cst_min10a mov a,r7 ;recover new value movx @r0,a ;save new minutes ten's value mov r0,#MIN movx @r0,a ;save copy too jmp ch_end ;increment minutes ones digit cst_min1 mov r0,#MIN_ ;get minutes movx a,@r0 add a,#01h ;increment ones digit (lower nibble) mov r7,a ;temp save it anl a,#0fh ;is new value = 10 xrl a,#10 jnz cst_min1a ;no mov a,r7 ;yes. change it to 0 anl a,#0f0h mov r7,a cst_min1a mov a,r7 ;recover new value movx @r0,a ;save new minutes ones value mov r0,#MIN movx @r0,a ;save copy too jmp ch_end ;increment seconds tens digit cst_sec10 mov r0,#SEC_ ;get seconds movx a,@r0 add a,#10h ;increment tens digit (upper nibble) mov r7,a ;temp save it anl a,#0f0h ;is new value = 6 xrl a,#60h jnz cst_sec10a ;no mov a,r7 ;yes. change it to 0 anl a,#0fh mov r7,a cst_sec10a mov a,r7 ;recover new value movx @r0,a ;save new seconds ten's value mov r0,#SEC movx @r0,a ;save copy too jmp ch_end ;set seconds ones digit to zero cst_sec1 mov r0,#SEC_ ;get seconds movx a,@r0 anl a,#0f0h ;change it to 0 movx @r0,a ;save new seconds ones value mov r0,#SEC movx @r0,a ;save copy too jmp ch_end ;******************* ;******************* org 600h ;toggle between AM & PM cst_ampm mov r0,#HOUR_ ;get hours data movx a,@r0 add a,#80h ;toggle bit 7 to toggle am/pm movx @r0,a ;save new am/pm setting mov r0,#HOUR movx @r0,a ;save copy too jmp ch_end ;toggle alarm between enabled & disabled cst_alm mov r0,#REGB_ ;get alarm enabled/disabled status movx a,@r0 jb5 cst_alm1 ;jump if currently enabled orl a,#20h ;enable alarm jmp cst_alm2 cst_alm1 anl a,#0dfh ;disable alarm cst_alm2 movx @r0,a ;save new alarm setting mov r0,#REGB movx @r0,a ;save copy too jmp ch_end ;increment thru weekday choices (1-7, 1=sunday) cst_weekday mov r0,#WKDAY_ ;get weekday value movx a,@r0 inc a ;increment it jb3 cst_wd1 ;jump if new value = 8 jmp cst_wd2 cst_wd1 mov a,#1 ;reset to 1 (sunday) cst_wd2 movx @r0,a ;save new weekday value mov r0,#WKDAY movx @r0,a ;save copy too jmp ch_end ;***** ;change set/alarm items csa call freeze in a,p2 ;what item is currently selected? mov r0,#CSELECT mov a,@r0 jb0 csa0 jb1 csa1 jb2 csa2 jb3 csa3 jb4 csa4 jb5 csa5 jb6 csa6 jb7 csa7 jmp ch_end csa0 jmp csa_hrs10 ;hours tens digit csa1 jmp csa_hrs1 ;hours ones digit csa2 jmp csa_min10 ;minutes tens digit csa3 jmp csa_min1 ;minutes ones digit csa4 jmp csa_sec10 ;seconds tens digit csa5 jmp csa_sec1 ;seconds ones digit csa6 jmp csa_ampm ;am/pm csa7 jmp csa_alm ;alarm enabled/disabled ;increment hours tens digit csa_hrs10 mov r0,#HOURA_ ;get hours movx a,@r0 add a,#10h ;increment tens digit (upper nibble) jb4 csa_hrs10a ;jump if tens digit is now 1 anl a,#0fh ;otherwise, make it 0 csa_hrs10a movx @r0,a ;save new hours ten's value mov r0,#HOURA movx @r0,a ;save copy too jmp ch_end ;increment hours ones digit csa_hrs1 mov r0,#HOURA_ ;get hours movx a,@r0 add a,#01h ;increment ones digit (lower nibble) mov r7,a ;temp save it anl a,#0fh ;is new value = 10 xrl a,#10 jnz csa_hrs1a ;no mov a,r7 ;yes. change it to 0 anl a,#0f0h mov r7,a csa_hrs1a mov a,r7 ;recover new value movx @r0,a ;save new hours ones value mov r0,#HOURA movx @r0,a ;save copy too jmp ch_end ;increment minutes tens digit csa_min10 mov r0,#MINA_ ;get minutes movx a,@r0 add a,#10h ;increment tens digit (upper nibble) mov r7,a ;temp save it anl a,#0f0h ;is new value = 6 xrl a,#60h jnz csa_min10a ;no mov a,r7 ;yes. change it to 0 anl a,#0fh mov r7,a csa_min10a mov a,r7 ;recover new value movx @r0,a ;save new minutes ten's value mov r0,#MINA movx @r0,a ;save copy too jmp ch_end ;increment minutes ones digit csa_min1 mov r0,#MINA_ ;get minutes movx a,@r0 add a,#01h ;increment ones digit (lower nibble) mov r7,a ;temp save it anl a,#0fh ;is new value = 10 xrl a,#10 jnz csa_min1a ;no mov a,r7 ;yes. change it to 0 anl a,#0f0h mov r7,a csa_min1a mov a,r7 ;recover new value movx @r0,a ;save new minutes ones value mov r0,#MINA movx @r0,a ;save copy too jmp ch_end ;increment seconds tens digit csa_sec10 mov r0,#SECA_ ;get seconds movx a,@r0 add a,#10h ;increment tens digit (upper nibble) mov r7,a ;temp save it anl a,#0f0h ;is new value = 6 xrl a,#60h jnz csa_sec10a ;no mov a,r7 ;yes. change it to 0 anl a,#0fh mov r7,a csa_sec10a mov a,r7 ;recover new value movx @r0,a ;save new seconds ten's value mov r0,#SECA movx @r0,a ;save copy too jmp ch_end ;increment seconds ones digit csa_sec1 mov r0,#SECA_ ;get seconds movx a,@r0 add a,#01h ;increment ones digit (lower nibble) mov r7,a ;temp save it anl a,#0fh ;is new value = 10 xrl a,#10 jnz csa_sec1a ;no mov a,r7 ;yes. change it to 0 anl a,#0f0h mov r7,a csa_sec1a mov a,r7 ;recover new value movx @r0,a ;save new seconds ones value mov r0,#SECA movx @r0,a ;save copy too jmp ch_end ;toggle between AM & PM csa_ampm mov r0,#HOURA_ ;get hours data movx a,@r0 add a,#80h ;toggle bit 7 to toggle am/pm movx @r0,a ;save new am/pm setting mov r0,#HOURA movx @r0,a ;save copy too jmp ch_end ;toggle alarm between enabled & disabled csa_alm mov r0,#REGB_ ;get alarm enabled/disabled status movx a,@r0 jb5 csa_alm1 ;jump if currently enabled orl a,#20h ;enable alarm jmp csa_alm2 csa_alm1 anl a,#0dfh ;disable alarm csa_alm2 movx @r0,a ;save new alarm setting mov r0,#REGB movx @r0,a ;save copy too jmp ch_end ;***************** ;***************** org 700h ;***** ;change set/date items csd call freeze in a,p2 ;what item is currently selected? mov r0,#CSELECT mov a,@r0 jb0 csd0 jb1 csd1 jb2 csd2 jb3 csd3 jb4 csd4 jb5 csd5 jmp ch_end csd0 jmp csd_mon10 ;month tens digit csd1 jmp csd_mon1 ;month ones digit csd2 jmp csd_day10 ;day tens digit csd3 jmp csd_day1 ;day ones digit csd4 jmp csd_yr10 ;year tens digit csd5 jmp csd_yr1 ;year ones digit ;increment month tens digit csd_mon10 mov r0,#MONTH_ ;get month movx a,@r0 add a,#10h ;increment tens digit (upper nibble) jb4 csd_mon10a ;jump if tens digit is now 1 anl a,#0fh ;otherwise, make it 0 csd_mon10a movx @r0,a ;save new month ten's value mov r0,#MONTH movx @r0,a ;save copy too jmp ch_end ;increment month ones digit csd_mon1 mov r0,#MONTH_ ;get month movx a,@r0 add a,#01h ;increment ones digit (lower nibble) mov r7,a ;temp save it anl a,#0fh ;is new value = 10 xrl a,#10 jnz csd_mon1a ;no mov a,r7 ;yes. change it to 0 anl a,#0f0h mov r7,a csd_mon1a mov a,r7 ;recover new value movx @r0,a ;save new month ones value mov r0,#MONTH movx @r0,a ;save copy too jmp ch_end ;increment day tens digit csd_day10 mov r0,#DAY_ ;get day movx a,@r0 add a,#10h ;increment tens digit (upper nibble) mov r7,a ;temp save it anl a,#0f0h ;is new value = 4 xrl a,#40h jnz csd_day10a ;no mov a,r7 ;yes. change it to 0 anl a,#0fh mov r7,a csd_day10a mov a,r7 ;recover new value movx @r0,a ;save new day ten's value mov r0,#DAY movx @r0,a ;save copy too jmp ch_end ;increment day ones digit csd_day1 mov r0,#DAY_ ;get day movx a,@r0 add a,#01h ;increment ones digit (lower nibble) mov r7,a ;temp save it anl a,#0fh ;is new value = 10 xrl a,#10 jnz csd_day1a ;no mov a,r7 ;yes. change it to 0 anl a,#0f0h mov r7,a csd_day1a mov a,r7 ;recover new value movx @r0,a ;save new day ones value mov r0,#DAY movx @r0,a ;save copy too jmp ch_end ;increment year tens digit csd_yr10 mov r0,#YEAR_ ;get year movx a,@r0 add a,#10h ;increment tens digit (upper nibble) mov r7,a ;temp save it anl a,#0f0h ;is new value = 10 xrl a,#0a0h jnz csd_yr10a ;no mov a,r7 ;yes. change it to 0 anl a,#0fh mov r7,a csd_yr10a mov a,r7 ;recover new value movx @r0,a ;save new year ten's value mov r0,#YEAR movx @r0,a ;save copy too jmp ch_end ;increment year ones digit csd_yr1 mov r0,#YEAR_ ;get year movx a,@r0 add a,#01h ;increment ones digit (lower nibble) mov r7,a ;temp save it anl a,#0fh ;is new value = 10 xrl a,#0ah jnz csd_yr1a ;no mov a,r7 ;yes. change it to 0 anl a,#0f0h mov r7,a csd_yr1a mov a,r7 ;recover new value movx @r0,a ;save new year ones value mov r0,#YEAR movx @r0,a ;save copy too jmp ch_end ;***** ;change set/stopwatch items css ;(not yet implemented) ;***** ;exit CHANGE button action ch_end call keyup ;wait for CHANGE button up call unfreeze jmp start0