IMD 1.17: 4/04/2010 8:05:34 Ampro LittleBoard SMARTCLOCK software disk    SMARTCLKCOM SMARTCLKZ80  ÌT!P~O8::y#B>AT!PO:Ow#B>A:(<(7!z:P~O8::yB#:\:\!!w#s1aSMARTCLK Ver 1.0 Copyright (c) 1986, AMPRO Computers, Inc. Usage: SMARTCLK - display date and time SMARTCLK /S - set SmartWatch SMARTCLK /T - test SmartWatch $'ڍ!~ʢ#~ (z/Tҧz/S &{&'8͕  > F Enter day of week (Mon-Sun) 2ʝzSUN>]zMON>]zTUE>]zWED>]zTHU>]zFRI>]zSAT>]F Invalid entryÝ2F Enter date (mm-dd-yyyy) 2!~GRʒҒ2#!Ғ2#!RҒ2F Enter time (hh:mm:ss) 2!~GR%җ2#Zҗ2#~(Zҗ22'&Ý&:͗='_!^#V&:͗='_!(^#V&:?!&: 8 !  ƀ!&&:!:!:!:!&~08:00bk)))_#R?Z} 0 Gy''' '0w#0w_ !>(wG#w ~(#~#=( < (~#(-(:(08:0G~([8_ ## 7OGyO Current date is $ ,$19 $20 $ - Time $ : : . $ Invalid date$ Invalid time$ error reading SmartWatch$@ISZaflrzJanuary $February $March $April $May $June $July $August $September $October $November $December $Sunday, $Monday, $Tuesday, $Wednesday, $Thursday, $Friday, $Saturday, $2*2121221212 * ;* * ;* SMARTCLK.Z80 for the LITTLE BOARD/PLUS * ;* Copyright (C) 1986 AMPRO Computers, Inc. * ;* ALL RIGHTS RESERVED. * ;* * ;* This code was developed for use with AMPRO hardware only. * ;* All other use is prohibited without prior written consent from * ;* AMPRO Computers, Inc. * ;* * ;****************************************************************************** ; ; version date by description ; ------- ------- ---- ----------------------------------------------- ; 1.0 2 nov 86 fsw Released version ; ; --------------------------------- page 62 ;****************************************************************************** ;* * ;* * ;* AAAMM MM PPPPPPPPPPPPP RRRRRRRRRRRR OOOOOOOOOOOOOO * ;* AAAAAMMM MMM PPPPPPPPPPPPP RRRRRRRRRRRR OOOOOOOOOOOOOO * ;* AAA AAA MMM MMM PPP PPP RRR OOO OOO * ;* AAA-------------------------------------------- ; NOTE: The Dallas SmartWatch will only work with the AMPRO LITTLE BOARD/PLUS ; model 1B-1 or 1B-2. ; ; The following modifications must be made to operate. On the back side ; of the board cut the trace going to pin 20 on the 28 pin EPROM socket ; labled U13. Solder a jumper between the eprom socked U13 pin 20 and ; pin 21 of the microprocessor labled U4. The SmartWatch will now ; function. ; ; May be assembled with a Z-80 assembler such as ZAS by MYTE AAA MMM MMM PPP PPPPPPPPP RRRRRRRRRRRR OOO OOO * ;* AAA AAA MMM MMM PPP PPPPPPPPP RRRRRRRRRRRR OOO OOO * ;* AAA AAA MMM PPP RRR OOO OOO * ;* AAA AAAAAAAAAA M PPP RRR OOOOOOOOOOOOOO * ;* AAA AAAAAAAAAAAA PPP RRR OOOOOOOOOOOOOO * ;* * ;* K available ; from ; Echelon, Inc. ; 885 N. San Antonio Road ; Los Altos, CA. 94022 ; (415)948-3820 ; ; ----------------------------------------------------------------------------- control equ 0 ; prom control port read equ 4 ; smartwatch read wrt1 equ 3 ; smartwatch write a 1 wrt0 equ 2 ; smartwatch write a 0 off equ 8000h-tpa ; offset for smartwatch interface cr equ 0dh ; carriage return lf equ 0ah ; line feed tpa equ 100h ; cpm tpa ; ------------------------- * ;* * ;* AMPRO COMPUTERS INCORPORATED * ;* 67 East Evelyn Avenue * ;* Mountain View, CA 94041 * ;* (415)962-0230 * ;* ----------------------------------------------- ; begining of code org tpa cmdline: equ $ ; all the code between this point ; and the label START: is moved above ; eprom memory space. it is then ; reused for command line and stack. jp start ; ************************************************************************ ; this code interfaces with the smartwatch and must be moved above the ; eprom memory space (0 to 8000h) to operate. the interface code is ; located between t he lines of '*' ; ; NOTE: the wakeup routine turns on the eprom socket and the readclk ; and setclk routines turn it off. ; ; new time to write to smartwatch is in clkbuff setclk: call wakeup+off ; init smartwatch ld hl,clkbuff+off ld b,8 ; number of bytes to write putbyte: ld d,b ; save byte count ld b,8 ; nunber of bits to write ld a,(hl) ; get byte to write putbit: rra ld c,a ; save jr c,putone ld a,(wrt0) ; write a zero jr pb1 putone: ld a,(wrt1) ; wr ; ************** End of SmartWatch interface code ************************ stack: equ $ ; use this area for stack oldstack ds 2 ; initialize memory space start: ld hl,tpa ; source ld de,8000h ; destination ld bc,movlen ; bytes to move ldir ; move program above rom space xor a,a ; clear a ld hl,tpa ; clear cmdline and stack area ld b,start-tpa clearcmd: ld (hl),a inc hl djnz clearcmd begin: ld (oldstack),sp ; save stack pointer ld sp,stack jp cont ; juita a one pb1: ld a,c ; get byte back djnz putbit inc hl ; next byte ld b,d ; byte count djnz putbyte ld a,41h ; turn off eprom out (control),a ret ; read the smartwatch registers, return with carry set if not sucessful readclk: call wakeup+off ; init smartwatch ld hl,clkbuff+off ; save area for read ld b,8 ; number of bytes to read getbyte: ld d,b ; save byte count ld b,8 ; set bit count to 8 xor a,a ; clear a ld c,a ; clear c getbit: ld a,(read) mp past help helpmsg: db 'SMARTCLK Ver 1.0' db cr,lf db 'Copyright (c) 1986, AMPRO Computers, Inc.' db cr,lf,lf db 'Usage: SMARTCLK - display date and time' db cr,lf db ' SMARTCLK /S - set SmartWatch' db cr,lf db ' SMARTCLK /T - test SmartWatch' db cr,lf db '$' cont: call readclk+off ; read the smartwatch jp c,swerror ; error reading smartwatch ld hl,80h ; point to command line buffer ld a,(hl) ; see if entry or a,a jp z,show$dt ; no, show and a,1 ; mask lsb or a,c ; or in bits rrc a ; move over for next bit ld c,a ; and save results djnz getbit ld (hl),a ; put in buffer inc hl ; next byte location ld b,d ; restore byte count djnz getbyte ld a,41h ; out (control),a ; turn off eprom ld a,(sw$reg4)+off and a,a ; set flags jr z,rderr ; register should be non-zero inc a ; see if 0ffh jr z,rderr ret rderr: scf ret ; initialize the smartclock ; NOTE: there is no stack whe date and time space: inc hl ld a,(hl) cp ' ' ; filter leading spaces jr z,space none: ex de,hl ; 'de' to command line call compare db '/T',0 ; test jp nc,test call compare db '/S',0 ; set time jp nc,settime ld de,helpmsg ; give help jr comm swerror: ld de,errmsg jr comm dateerr: ld de,dterrmsg jr comm timeerr: ld de,tmerrmsg comm: call print$string exit: ld sp,(oldstack) ; and exit ret ; show the date and time show$dt: call shw$dt ; n the prom socket is turned on. wakeup: pop ix ; put ret address in 'ix' xor a,a out (control),a ; prom socket is now on ld hl,wakepat+off ld b,8 ; byte count ld a,(read) ; reset clock wakebyte: ld d,b ; save byte count in 'd' ld b,8 ; bit count ld a,(hl) ; get first char wakebit: rra ld c,a ; save jr c,wrtone ld a,(wrt0) ; write zero jr wake1 wrtone: ld a,(wrt1) ; write one wake1: ld a,c ; restore pattern djnz wakebit ; bit count ld b,d ; gdisplay date and time jr exit ; test the smartwatch by reading until interrupted by console input test: call readclk+off jr c,swerror call showtime ld c,11 ; get console status call 5 or a,a jr nz,testend ; if any char typed ld a,cr call print$char jr test testend: ld c,1 ; con input call 5 ; get the character jr exit ; and throw away ; set the date and time settime: call print db cr,lf,'Enter day of week (Mon-Sun) ',0 call rdbuff ; get input et byte count back inc hl ; next pattern location djnz wakebyte jp (ix) ; return wakepat: db 0c5h,03ah,0a3h,05ch,0c5h,03ah,0a3h,05ch clkbuff: ; 8 byte save area for smartclk reg sw$reg0: db 0 ; tenths, hundredths seconds (00-99) sw$reg1: db 0 ; seconds (00-59) sw$reg2: db 0 ; minutes (00-59) sw$reg3: db 0 ; hour (00-23) sw$reg4: db 0 ; day (01-07) sw$reg5: db 0 ; date (01-31) sw$reg6: db 0 ; month (01-12) sw$reg7: db 0 ; year (00-99) movlen: equ $-tpa  ld de,cmdline+1 ; see if input ld a,(de) or a,a jp z,exit inc de call compare db 'SUN',0 ld a,1 jp nc,stm1 call compare db 'MON',0 ld a,2 jp nc,stm1 call compare db 'TUE',0 ld a,3 jp nc,stm1 call compare db 'WED',0 ld a,4 jp nc,stm1 call compare db 'THU',0 ld a,5 jp nc,stm1 call compare db 'FRI',0 ld a,6 jp nc,stm1 call compare db 'SAT',0 ld a,7 jp nc,stm1 error: call print db cr,lf,'Invalid entry',0 jp  exit stm1: or a,10h ; set reset bit ld (sw$reg4)+off,a ; day of week to smartwatch reg call print db cr,lf,'Enter date (mm-dd-yyyy) ',0 call rdbuff ld hl,cmdline+1 ld a,(hl) or a,a jp z,error call valid ; test for valid numeric entry call strng2bcd ; convert cmdline to bcd or a,a ; valid month (01-12) jp z,dateerr cp 12h+1 jp nc,dateerr ld (sw$reg6)+off,a ; put month inc hl push de ; save binary month call strng2bcd ; get date pop de ; get  sub 20h ; sub 21st century offset call a2asc ld de,cen21 jr prn$yr twnty: add 80h ; add offset for 1980 ld hl,cen20a call a2asc ld de,cen20 prn$yr: call print$string show$time$msg: ld de,timemsg call print$string showtime: ld a,(sw$reg3)+off ; get hour ld hl,hrmsg call a2asc ld a,(sw$reg2)+off ; get minute ld hl,minmsg call a2asc ld a,(sw$reg1)+off ; get second ld hl,secmsg call a2asc ld a,(sw$reg0)+off ; get hundredth of second ld hbinary month back push hl ; save pointer dec de ; make month 0 to 11 ld hl,mnths ; offset to number of days in month add hl,de cp (hl) ; see if more than max days in month pop hl ; jp nc,dateerr ld (sw$reg5)+off,a ; inc hl call strng2bcd ; get year ld hl,1979 ; make sure 4 digit century entered sbc hl,de ; 'de'=binary century jp p,dateerr cp 99h+1 ; more than 99 jp nc,dateerr ld (sw$reg7)+off,a ; store year call print db cr,lf,'Enter time (hl,hunmsg call a2asc ld de,hrmsg ; display the time call print$string ret ; convert decimal character string pointed to by 'hl'. ; returns: 'a' equal to bcd value between 0 and 99. ; 'de' equals the binary value of string ; 'hl' points to delimiter ; strng2bcd: push bc ; save ld de,0 stng1: ld a,(hl) ; get char cp '0' jr c,stngext ; less than ascii '0' cp '9'+1 jr nc,stngext ; more than ascii '9' sub '0' stng10: push hl ; save pointer ld h,dh:mm:ss) ',0 call rdbuff ; get input ld hl,cmdline+1 ld a,(hl) ; get number of characters typed or a,a jp z,error ; no input call valid ; test for valid numeric asci call strng2bcd ; get hour cp 24h+1 jp nc,timeerr ; ld (sw$reg3)+off,a ; store hour inc hl call strng2bcd ; get minute cp 59h+1 jp nc,timeerr ld (sw$reg2)+off,a ; store minute inc hl ld a,(hl) or a,a ; see if seconds entered jr z,stm4 call strng2bcd ; get seconds cp 59h+1  ; multiply de x10 ld l,e add hl,hl ; *2 add hl,hl ; *4 add hl,de ; *5 add hl,hl ; *10 ld e,a ld d,0 add hl,de ex de,hl pop hl inc hl jr stng1 ; convert the binary value in 'de' to bcd value between 0 and 99 in 'a'. stngext: push de ; save bcd value push hl ; save pointer xor a,a ; clear flags ex de,hl ld de,1980 sbc hl,de ; sub 1980 jp p,cvt ; ok if positive ccf ; was set if here adc hl,de ; add it back cvt: ld a,l ; 'a'= 0h  jp nc,timeerr stm4: ld (sw$reg1)+off,a xor a,a ld (sw$reg0)+off,a ; clear hundreths of seconds call setclk+off ; set the time call readclk+off ; show the date and time call shw$dt jp exit ; show date and time shw$dt: ld de,curmsg call print$string ld a,(sw$reg4)+off ; get day of week and a,07h ; mask off extra call bcd2bin ; dec a ; make 0 to 6 sla a ; x2 ld e,a ld d,0 ld hl,dayofweek add hl,de ld e,(hl) inc hl ld d,(hl) ; print dto 63h ld c,0ffh ; lp10: inc c sub 10 ; -10 loop jr nc,lp10 add 10 ; make back positive ld b,a ; save 1's ld a,c ; get 10's sla a sla a sla a sla a ; 10's to upper nibble or a,b ; or in 1's pop hl pop de pop bc ret ; convert bcd number in 'a' to ascii and store number to 'hl' and 'hl'+1 a2asc: push af and a,0f0h ; do upper nibble rra rra rra rra or a,'0' ld (hl),a inc hl pop af ; do lower nibble and a,0fh or a,'0ay of week call print$string ld a,(sw$reg6)+off ; get month and a,1fh ; mask month (01 to 12) call bcd2bin dec a ; make 0 to 11 sla a ; x2 ld e,a ld d,0 ld hl,month add hl,de ld e,(hl) inc hl ld d,(hl) ; month string in 'de' call print$string ld a,(sw$reg5)+off ; get date and a,3fh ; mask (01 to 31) ld hl,date call a2asc ld de,date call print$string ld a,(sw$reg7)+off ; get year cp 20h ; less than 20 jr c, twnty ld hl,cen21a' ld (hl),a ret ; print the char in 'a' print$char: push bc push de push hl ld e,a ld c,2 ; print character call 5 ; cp/m pop hl pop de pop bc ret ; cpm function 9h, print string terminated with '$'. ; "de" points to string address print$string: push af push bc push hl ld c,9 call 5 ; cpm entry pop hl pop bc pop af ret ; get command line input rdbuff: ld hl,cmdline ; point to command line push hl ld a,40 ld (hl),a ; 4 0 character command line ld b,a ; set up count for clear buffer xor a ; clear buffer clrbuff: inc hl ld (hl),a djnz clrbuff pop de ; get command line ptr back to 'de' ld c,10 call 5 ret ; print a ascii string terminated with '0' contained in the code print: pop hl ; string address is on stack ld a,(hl) or a,a ; see if end jr z,prnend call print$char ; print the character inc hl jr print+1 prnend jp (hl) ; scan the command line for valid entry ; ay3 dw day4 dw day5 dw day6 dw day7 month: dw mon1 dw mon2 dw mon3 dw mon4 dw mon5 dw mon6 dw mon7 dw mon8 dw mon9 dw mon10 dw mon11 dw mon12 mon1: db 'January $' mon2: db 'February $' mon3: db 'March $' mon4: db 'April $' mon5: db 'May $' mon6: db 'June $' mon7: db 'July $' mon8: db 'August $' mon9: db 'September $' mon10: db 'October $' mon11: db 'November $' mon12: db 'December $' day1: db 'Sunday, $' day2: db 'Monday, $' dcalled with 'hl' pointing to command line count valid: ld a,(hl) ; get number of characters typed inc hl dec a ; make sure more than one char jr z,notvalid+1 inc a ; restore value cp ' ' jr z,valid ; filter spaces push hl ; save pointer to first char valid1: ld a,(hl) inc hl and a,a jr z,validext cp '-' jr z,valid1 cp ':' jr z,valid1 cp '0' jr c,notvalid cp '9'+1 jr nc,notvalid jr valid1 validext: pop hl ret notvalid: pop hl jay3: db 'Tuesday, $' day4: db 'Wednesday, $' day5: db 'Thursday, $' day6: db 'Friday, $' day7: db 'Saturday, $' mnths: db 31h+1,29h+1,31h+1,30h+1,31h+1,30h+1 db 31h+1,31h+1,30h+1,31h+1,30h+1,31h+1 end h $' mon4: db 'April $' mon5: db 'May $' mon6: db 'June $' mon7: db 'July $' mon8: db 'August $' mon9: db 'September $' mon10: db 'October $' mon11: db 'November $' mon12: db 'December $' day1: db 'Sunday, $' day2: db 'Monday, $' dp error ; compare a string of characters addressed by 'de' to string ; pointed to by stack address. compare: ex (sp),hl ; push de ; save source address cmpa: ld a,(hl) and a,a ; zero is end jr z,same ; yes, string was equal ld a,(de) ; get string char cp 'Z'+1 ; less than 'Z' jr c,cmpb and 5fh ; make upper case cmpb: cp (hl) ; compare jr nz,notsame ; not the same inc hl ; next characters inc de jr cmpa ; till through or not same notsame: xor a,a ; keep going till end of string inc hl cp (hl) jr nz,notsame+1 scf ; show error same: pop de ; restore source address ex (sp),hl ; 'hl' has return address ret ; BCD to Binary ; 'A' = bcd number to convert, returns biniary number in 'A' ; bcd2bin: push bc ld c,a ; save for a moment and 0fh ; make low nibble ld b,a ; save it ld a,c ; get bcd back and 0f0h ; upper nibble rrca ; to low nibble rrca rrca rrca add a,a ; x 2 ld c,a ; save results add a,a ; x 4 add a,a ; x 8 add a,c ; x10 add a,b ; have biniary equivalent in 'a' pop bc ret curmsg: db cr,lf,'Current date is $' date: db ' ,$' cen20: db '19' cen20a: db ' $' cen21: db '20' cen21a: db ' $' timemsg: db ' - Time $' hrmsg: db ' :' minmsg: db ' :' secmsg: db ' .' hunmsg: db ' $' dterrmsg: db cr,lf,'Invalid date$' tmerrmsg: db cr,lf,'Invalid time$' errmsg: db cr,lf,'error reading SmartWatch$' dayofweek: dw day1 dw day2 dw d                                                                 ! ! " " # # $ $ % % & & ' '