File "Clk_Demo.asm"
Full Path: /home/analogde/www/chart-export-handler/Projet/Clk_Demo.asm
File size: 24.78 KB
MIME-type: text/x-c
Charset: utf-8
*
**********************************
* CLOCK DEMO *
* *
* Demo of the DS1302 clock chip *
* and Junian Date & day-of-week *
* software. *
*********************************
*
*
* Written by:
* Roger Schaefer
* BCD Inc.
* 3133 South Illinois
* Belleville, IL 62220
* rsch@ezl.com
*
* http://www.ezl.com/~rsch
*
* PROCESSOR IS: MC9S12DP256 running at 24 MHz
* This program is written to be run in RAM
* D-Bug12 v 4.x.x monitor is present
* "load" the S19 file and "G 2000"
*
*
* The following Equates are for IF statements
* in the source file
*
*EXPAND EQU 1 ;The listing of includes
*
*FLASH EQU 1
*
RAMONLY EQU 1 ;use RAM only
*
* LANGUAGE USED IS:
ENGLISH EQU 0 ;value doesn't matter
* Real Time Clock is
DS1302 EQU 0 ;from Dallas is installed
*
*********************************************************
*
***************
* EQUATES *
***************
*
RAMSTRT: EQU $1000 ; start of internal ram
MONRAM: EQU $2000 ; monitor ram start
REGBS: EQU $0000 ; start of registers
ROMBS: EQU $8000 ; start of paged rom
DSTREE: EQU $0400 ; start of eeprom
DENDEE: EQU $0FFF ; end of eeprom
STACK: EQU $2000 ; top of stack
;OscClk: equ 8000000
;Eclock: equ 24000000 ; final E-clock frequency (PLL)
;RefClock: equ 8000000
;
REFDVVal: equ 0 ;(OscClk/RefClock)-1
SYNRVal: equ 2 ;(Eclock/RefClock)-1
FCLKDIVVal: equ 40 ;(OscClk/200000)
*
*
* Processor registor listing below
*
#ifdef EXPAND
#include Reg9s12.i
#else
nolist
#include Reg9s12.i
list ;resume the listing
#endif
*
*
* Serial Peripheral Status Reg. bits
SPIF EQU %10000000
* Serial Peripheral Control Reg. bits
LSBF EQU %00000001
*
* Serial Communication Interface Status Reg. bits
TC EQU %01000000 ;transmit complete
RDRF EQU %00100000 ;receive data full
TE EQU %00001000 ;transmit enable
TCIE EQU %01000000 ;TC interrupt enable
*
* Timer Interrupt Flag Register 1 bits
C0F EQU %00000001
C1F EQU %00000010
C2F EQU %00000100
C3F EQU %00001000
C4F EQU %00010000
C5F EQU %00100000
C6F EQU %01000000
C7F EQU %10000000
*
* Pulse Accumulator Control Register bits
DDRA7 EQU %10000000 ;data dir reg bit 7
PAEN EQU %01000000 ;pulse accumulator
;enable
PAMOD EQU %00100000 ;pulse acc mode sel
PEDGE EQU %00010000 ;pulse acc edge sel
*
* Pulse Accumlator Interrupt Flag & Enable
PAOVI EQU %00100000 ;enable in TMSK2
PAII EQU %00010000 ; " "
PAOVF EQU %00100000 ;flag in TFLG2
PAIF EQU %00010000 ; " "
*
* Bit definitions for the CRGFLG register
LOCK: equ $08
*
* Bit definitions for the CLKSEL register
PLLSEL: equ $80 ; use PLL for system clocks.
*
QUELNG EQU 16 ;size of input queue
*
*
PROMPT EQU '>'
*
*
*
PR2PR1PR0 EQU %000 ;Timer Prescaler Select
PRESCALE EQU 64 ;if PR2:1:0 = 000 set to 64
;if PR2:1:0 = 001 set to 32
; 010 set to 16
; 011 set to 8
; 100 set to 4
; 101 set to 2
;
MSec EQU 375 ; @ 24MHz clock use 375
; use: #ms*MSec*PRESCALE
uSec EQU 24 ; use: #us*uSec
*
*****************************
USTACK EQU STACK-200
*****************************
BUFFLNG EQU 64
*
IO equ portt ;port to use for output
IODDR equ ddrt
RTClkPort equ portm
RTClkDDR equ ddrm
RST equ %10000000
SCLK equ %01000000
I_O equ %00100000
*
*
*
MinDigit EQU 7 ;for leading zero
*
*
ORG RAMSTRT
*
*
*
.10ms RMB 1
JIFFY RMB 1
SEC RMB 1
MIN RMB 1
HR RMB 1
DAY RMB 1
CLK RMB 1
*
* Clock flag bits
*
NewSec EQU %00000001
NewMin EQU %00000010
NewHr EQU %00000100
NewDay EQU %00001000
NewPM EQU %00010000
NewJif EQU %00100000
*
*
*** Buffalo variables - used by: ***
*
PTR0 RMB 2 ;main,readbuff,incbuff,AS
PTR1 RMB 2 ;main,BR,DU,MO,AS
PTR2 RMB 2 ;DU,GO,MO,AS
PTR3 RMB 2 ;HO,MO,AS
TMP1 RMB 1 ;main,hexbin,buffarg,termarg
TMP2 RMB 1 ;GO,HO,AS
TMP3 RMB 1 ;AS,LOAD
TMP4 RMB 1 ;GO,HO,ME,AS
*
SHFTREG RMB 3 ;input shift register
REGS RMB 9 ;user's pc,y,x,a,b,c
SP RMB 2 ;user's sp
STREE RMB 2 ;eeprom start address
ENDEE RMB 2 ;eeprom end address
YEAR RMB 1
AUTOLF RMB 1 ;auto lf flag for i/o
IODEV RMB 1 ;0=sci, 1=acia, 2=duartA
;3=duartB, 4=MAX3100
EXTDEV RMB 1 ;0=none, 1=acia, 2=duart
HOSTDEV RMB 1 ;0=sci, 1=acia, 3=duartB
COUNT RMB 1 ;# characters read
CHRCNT RMB 1 ;# characters output on
; current line
PTRMEM RMB 2 ;current memory location
LDOFFST RMB 2 ;offset for download
DBUFR RMB 9 ;Decimal result buffer
;(8 bytes ASCII)
* Some routines use only first 5 bytes of DBUFR
HTEMP RMB 3 ;Temp for H6TOD8 (3 bytes)
RESET_TYPE RMB 1
UCLK RMB 1 ;user clock flags
BTemp RMB 1 ;temp for B in MAIN loop
*
FLG RMB 1 ; Flags
*
* FLG BITS
*
LeapYr EQU %00000001 ;is this a Leap Year
QFULL EQU %00000010 ;input queue is full
ECHO EQU %00000100 ;echo input character?
NEWCHAR EQU %00001000 ;new character
*
;-------------
;RTC Variables
;-------------
;
DATA rmb 1
ACKCT rmb 1
*
*
QHEAD RMB 1
QTAIL RMB 1
QAVAIL RMB 1
QUEUE RMB QUELNG
QUEUEZ EQU * ;marker for end of queue
TX rmb 2
RX rmb 2
TXmask rmb 1
*
* for Zeller Congrence
ZELLER RMB 18
;dayZ RMB 2
;yrZ RMB 2
;mnZ RMB 2
;n1Z RMB 2
;n2Z RMB 2
;n3Z RMB 2
;YearZ RMB 2
;MonthZ RMB 2
;DateZ RMB 2
*
lcd_temp RMB 1
linechar RMB 1
lineno RMB 1
st_lo RMB 1
lcd_data RMB 1
*
CKSM RMB 1 ;checksum
TEMP RMB 1
TW RMB 2
MCONT RMB 1
*
Sec_Temp RMB 4 ;for WRITE_EEPROM_BYTE
*
ZZRAM EQU *
*
*
*****************
INBUFF RMB BUFFLNG
BUFFEND RMB 1 ;EOS stuck here sometimes
COMBUFF RMB 8
msgbuff rmb BUFFLNG
rmb 1 ;EOS stuck here
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
* org $2000
;
* Following bytes need to be in battery backed RAM
BaseYr RMB 1 ;start with 98 BCD
*
*
;
#ifdef RAMONLY
ORG $2000
#else
ORG ppage
fcb #$34 ; FLASH page
ORG ROMBS
#endif
*
***********************
*
.BUFISIT JMP BUFISIT
*
*.ForceQ JMP ForceQ ;use A,B,X
*
COP_SERVICE EQU *
LDAA #$55
STAA RESET_TYPE
*
BUFISIT EQU *
SEI
LDAA #REGBS/$100 ;Registers
STAA $11 ;INITRG
LDAA #RAMSTRT/$100 ;Ram
STAA initrm
#ifdef RAMONLY
#else
ldab #REFDVVal ; set the REFDV register to give us a
stab refdv ; ....1.0 MHz reference.
ldab #SYNRVal ; set the SYNR register to give us a
stab synr ; ....24.0 MHz E-clock.
nop ; nops required for bug in initial silicon.
nop
nop
nop
brclr crgflg,#LOCK,* ; wait here till the PLL is locked.
bset clksel,#PLLSEL ; switch the bus clock to the PLL.
;
ldab #FCLKDIVVal ; value for the Flash & EEPROM clock
stab fclkdiv ; ....divider register.
stab eclkdiv
#endif
LDAA #%00000111 ;COP rate
STAA copctl
LDAA #%11100000
STAA intcr ;dly, irqe
LDAA #PR2PR1PR0
ORAA tmsk2
STAA tmsk2 ;timer pre = /4
;Set up external memory control registers
LDS #STACK
CLR EXTDEV
CLR IODEV
JSR INIT ;initialize IO; set baud
JSR SET_LYr
*
JSR CLS ;clear screen if ANSI installed
JSR SignOn
JSR OUTCRLF
JSR SHOW_TIME
JSR OUTCRLF
JSR SHOW_DATE
JSR OUTCRLF
JSR PRTJULIAN
JSR OUTCRLF
JMP MAIN
************************************************************
*
************************************************************
*
PRTJULIAN EQU *
LDX #MSG79 ;"The JULIAN Date...
JSR OUTSTRG0
JSR JULIAN_BIN
LDX #PTR3
PRTJ1 JSR HTOD ;make ASCII
LDX #DBUFR+2 ;100's digit
LDAA #EOS
STAA DBUFR+5
JSR OUTSTRG0
RTS
*
*
* JULIAN IN BINARY -- Find the Julian day and
* return is binary value
* in PRT3; used by both
* JULIAN and WEEK
JULIAN_BIN EQU *
JSR Get_Month
TAB
ANDA #$F ;mask off 10's
ANDB #$F0 ;save just 10's
BEQ JUL1
ADDA #10
JUL1 TAB
BRSET FLG, LeapYr, JUL2
LDY #MonthTbl
BRA JUL3
JUL2 LDY #MonthTbl_L
JUL3 ASLB ;times two
ABY
LDD ,Y ;get number days
STD PTR3
JSR Get_Date
BSR BCDTOB ;convert to binary
TAB ;move to B
CLRA
ADDD PTR3 ;add to months
STD PTR3
RTS
*
*
*
* BCDTOB (A) Enter with a two digit BCD number in
* reg A; return with binary in A.
* Does no error checking.
*
BCDTOB PSHB
TAB
LSRB
LSRB
LSRB
LSRB ;10's in B
ANDA #$F ;1's in A
PSHA
LDAA #10
MUL ;result in B
PULA
ABA ;combine
PULB
RTS
*
*
* TIME -- Display real time clock using the same
* format as DOS
*
SHOW_TIME EQU *
LDX #MSG20 ;"Current ...
JSR OUTSTRG0
JSR Get_Hour
PSHA
ANDA #$30
LSRA
LSRA
LSRA
LSRA
BNE SET_T0
LDAA #$F0
SET_T0 EQU *
JSR OUTRHLF
PULA
ANDA #$F
JSR OUTRHLF
LDAA #':
JSR OUTPUT
JSR Get_Minutes
PSHA
LSRA
LSRA
LSRA
LSRA
JSR OUTRHLF
PULA
ANDA #$F
JSR OUTRHLF
LDAA #':
JSR OUTPUT
JSR Get_Seconds
PSHA
ANDA #$7F
LSRA
LSRA
LSRA
LSRA
JSR OUTRHLF
PULA
ANDA #$F
JSR OUTRHLF
JSR OUTSPAC
JSR Get_Hour
TSTA
BPL SET_T9
BITA #%00010000
BEQ PM
LDAA #'a
SET_T1 JSR OUTPUT
LDAA #'m
JSR OUTPUT
* LDX #MSG21 ;"Enter new ...
* JSR OUTSTRG
SET_T9 RTS
PM LDAA #'p
BRA SET_T1
*
*
* DATE -- Show the real time clock
*
*
SHOW_DATE EQU *
LDX #MSG22 ;"Current ..
JSR OUTSTRG0
JSR Show_day_of_week
*------------------------------------------------
JSR Get_Month
PSHA
BITA #%00010000
BNE SET_D1
LDAA #SPACE
SET_D0 JSR OUTPUT
PULA
ANDA #$F
JSR OUTRHLF
LDAA #'-
JSR OUTPUT
*-------------------------------------------------
JSR Get_Date
PSHA
LSRA
LSRA
LSRA
LSRA
JSR OUTRHLF
PULA
ANDA #$F
JSR OUTRHLF
LDAA #'-
JSR OUTPUT
*-------------------------------------------------
JSR SET_LYr ;get year
PSHA
CMPA #$94
BLS SET_D2
BSR OUT19
SET_D3 LSRA
LSRA
LSRA
LSRA
JSR OUTRHLF
PULA
ANDA #$F
JSR OUTRHLF
* LDX #MSG23
* JSR OUTSTRG
RTS
*
OUT19 PSHA
LDAA #'1
JSR OUTPUT
LDAA #'9
JSR OUTPUT
PULA
RTS
OUT20 PSHA
LDAA #'2
JSR OUTPUT
LDAA #'0
JSR OUTPUT
PULA
RTS
RTS
SET_D1 LDAA #'1
BRA SET_D0
SET_D2 BSR OUT20
BRA SET_D3
*
*
* SET LEAP YEAR - returns with year in A and
* sets the leap year flag
*
SET_LYr:
LDAA #6 ;year
JSR READ_CLK
PSHA
JSR BCDTOB ;convert to binary
;added ver 0.83
STAA YEAR
LSRA
BCS NOT_LYr
LSRA
BCS NOT_LYr
BSET FLG, LeapYr ;is leap year
PULA
RTS
NOT_LYr BCLR FLG, LeapYr ;isn't leap year
PULA
RTS
*
*
Get_Full_Year:
jsr Get_Year ;from RTC in BCD
jsr BCDTOB
tab
clra
cmpb #94 ;compare to 1994
bls Get_Full_Year1
addd #1900
bra Get_Full_Year2
Get_Full_Year1:
addd #2000
Get_Full_Year2:
rts
*
Show_Day_of_Week:
bsr Get_day_of_week
jsr OUTSTRG0
rts
Get_day_of_week:
jsr Get_Date ;return 1 to 31
jsr BCDTOB
tab
clra
std DateZ
*
jsr Get_Month
jsr BCDTOB
tab
clra
std MonthZ
*
jsr Get_Full_Year
std YearZ
*
sei
jsr Compute_Day ;day returned in A
cli
lsla ;times two
ldx #Days_of_Week
leax a,x
ldx 0,x
rts
*
*
*
*********************
*** COMMAND TABLE ***
*********************
*
COMTABL EQU *
*
*** Command names for current application ***
*
IFDEF DS1302
INCLUDE "clk_cmd.i"
ENDIF
FCB 4
FCC 'HELP'
FDB HELP
FCB 3
FCC 'CLS'
FDB CLS
FCB -1
*
*
*
*****************
* UTILITY SUBROUTINES - These routines
* are called by any of the task routines.
*****************
*
*****************
* UPCASE(a) - If the contents of A is alpha,
* returns a converted to uppercase.
*****************
UPCASE CMPA #'a'
BLT UPCASE1 ;jump if < a
CMPA #'z'
BGT UPCASE1 ;jump if > z
SUBA #$20 ;convert
UPCASE1 RTS
*
*
*****************
* HEXBIN(a) - Convert the ASCII character in a
* to binary and shift into shftreg. Returns value
* in tmp1 incremented if a is not hex.
*****************
HEXBIN PSHA
PSHB
PSHX
JSR UPCASE ;convert to upper case
CMPA #'0'
BLT HEXNOT ;jump if a < $30
CMPA #'9'
BLE HEXNMB ;jump if 0-9
CMPA #'A'
BLT HEXNOT ;jump if $39> a <$41
CMPA #'F'
BGT HEXNOT ;jump if a > $46
ADDA #$9 ;convert $A-$F
HEXNMB ANDA #$0F ;convert to binary
LDX #SHFTREG
LDAB #4
HEXSHFT ASL 1,X ;2 byte shift through
ROL 0,X ; carry bit
DECB
BGT HEXSHFT ;shift 4 times
ORAA 1,X
STAA 1,X
BRA HEXRTS
HEXNOT INC TMP1 ;indicate not hex
HEXRTS PULX
PULB
PULA
RTS
*
*
*****************
* BUFFARG() - Build a hex argument from the
* contents of the input buffer. Characters are
* converted to binary and shifted into shftreg
* until a non-hex character is found. On exit
* shftreg holds the last four digits read, count
* holds the number of digits read, ptrbuff points
* to the first non-hex character read, and A holds
* that first non-hex character.
*****************
*Initialize
*while((a=readbuff()) not hex)
* hexbin(a);
*return();
*
BUFFARG CLR TMP1 ;not hex indicator
CLR COUNT ;# or digits
CLR SHFTREG
CLR SHFTREG+1
JSR WSKIP
BUFFLP JSR READBUFF ;read char
JSR HEXBIN
TST TMP1
BNE BUFFRTS ;jump if not hex
INC COUNT
JSR INCBUFF ;move buffer pointer
BRA BUFFLP
BUFFRTS RTS
*
*
*****************
* READBUFF() - Read the character in "msgbuff"
* pointed at by ptrbuff into A. Returns ptrbuff
* unchanged.
*****************
READBUFF PSHX
LDX PTR0
LDAA 0,X
PULX
RTS
*
*****************
* INCBUFF(), DECBUFF() - Increment or decrement
* ptrbuff.
*****************
INCBUFF PSHX
LDX PTR0
INX
BRA INCDEC
DECBUFF PSHX
LDX PTR0
DEX
INCDEC STX PTR0
PULX
RTS
*
*
*****************
* WSKIP() - Read from the msgbuff until a
* non whitespace (space, comma, tab) character
* is found. Returns ptrbuff pointing to the
* first non-whitespace character and a holds
* that character. WSKIP also compares a to
* $0D (CR) and cond codes indicating the
* results of that compare.
*****************
WSKIP JSR READBUFF ;read character
BSR WCHEK
BNE WSKIP1 ;jump if not wspc
JSR INCBUFF ;move pointer
BRA WSKIP ;loop
WSKIP1 CMPA #$0D ;is CR
RTS
*
*****************
* WCHEK(a) - Returns z=1 if a holds a
* whitespace character, else z=0.
*****************
WCHEK CMPA #$2C ;comma
BEQ WCHEK1
CMPA #$20 ;space
BEQ WCHEK1
CMPA #$09 ;tab
WCHEK1 RTS
*
*****************
* DCHEK(a) - Returns Z=1 if a = whitespace
* or carriage return. Else returns z=0.
*****************
DCHEK BSR WCHEK
BEQ DCHEK1 ;jump if whitespace
CMPA #$0D
DCHEK1 RTS
*
*
COPRESET: ;reset cop
MOVB #$55,armcop
MOVB #$AA,armcop
RTS
*
HELP EQU *
LDX #HELPMSG
JSR OUTSTRG ;print help screen
RTS
*
SignOn:
LDX #MSG1 ;BUFFALO message
JSR OUTSTRG
RTS
*
CLS LDX #MSG17
JSR OUTSTRG
RTS
*
*
*
* MONTH TABLE - A list of the number of days in
* each month
*
MonthTbl FDB 0
FDB 0
FDB 31 ;January
FDB 59 ;Febuary
FDB 90 ;March
FDB 120 ;April
FDB 151 ;May
FDB 181 ;June
FDB 212 ;July
FDB 243 ;August
FDB 273 ;September
FDB 304 ;October
FDB 334 ;November
Dec FDB 365 ;December
*
* MONTH TABLE - YEAP YEAR
*
MonthTbl_L EQU *
FDB 0
FDB 0
FDB 31
FDB 60 ;Feb+1
FDB 91 ;March+1
FDB 121 ;April+1
FDB 152 ;May+1
FDB 182 ;June+1
FDB 213 ;July+1
FDB 244 ;Aug+1
FDB 274 ;Sept+1
FDB 305 ;Oct+1
FDB 335 ;Nov+1
DecYLr FDB 366 ;Dec+1
*
*
Days_of_Week:
FDB MSG63 ;SUNDAY
FDB MSG64
FDB MSG65
FDB MSG66
FDB MSG67
FDB MSG68
FDB MSG69
FDB MSG9
*
*
INCLUDE "main.i"
INCLUDE "Zeller64.i"
* INCLUDE "Mul16x16.i"
* INCLUDE "Div32x16.i"
INCLUDE "HTOD.I"
INCLUDE "utility.i"
INCLUDE "io.i"
* INCLUDE "io_irq.i" ;NOTE: cannot use SCI0 and
* ;D-Bug12 so can't use io_irq.i
*
**************************************************
* routine to implement general purpose timer, with
* 1 ms increments call with desired time period in
* acc. Routine implements a 1 ms loop.
*
time1ms staa st_lo
LDAA #$80
STAA tscr ;enable timer system
LDAA #C2F
ORAA tios ;timer two selected
STAA tios ;...as output compare
pshb
timer2:
ldd tcnt
addd #1*MSec*PRESCALE
std tc2
ldaa #C2F
staa tflg1 ; clear flag
timeloop:
brclr tflg1, #C2F, timeloop
ldaa #C2F
staa tflg1 ; clear flag
dec st_lo ;dec count on each underflow
bne timer2 ;exit when time_count = 0
pulb
rts
*
* wait for 100 milliseconds
wait100ms:
psha
ldaa #100
bsr time1ms
pula
rts
*
* wait for 10 milliseconds
DLY10MS:
wait10ms:
psha
ldaa #10
bsr time1ms
pula
rts
*
*
* wait for 1 millisecond
wait1ms:
psha
ldaa #1
bsr time1ms
pula
rts
*
*********************************************************
* If we have a DS1302 chip installed then load driver *
* else *
* simulate to demostrate the rest of the software. *
*********************************************************
IFDEF DS1302
INCLUDE "DS1202.I"
ELSE
Get_Seconds:
lda #$00
rts
Get_Minutes:
lda #$00
rts
Get_Hour:
lda #%10000111
rts
Get_Date:
lda #$23
rts
Get_Month:
lda #$07
rts
Get_Year:
lda #$03
rts
ENDIF
************************************************************
*
*************************
* MESSAGE SCREEN *
*************************
*
MSG1 FCC 'Demonstration of DS1302 Real Time Clock'
FCB CR
FCC 'Type HELP for commands'
FCB CR
FCB EOT
MSG17 FCB $1B
FCC '[2J'
FCB EOT
MSG20 FCC 'Current time is '
FCB EOT
MSG21 FCC 'Enter new time: '
FCB EOT
MSG22 FCC 'Current date is '
FCB EOT
MSG23 FCC 'Enter new date (mm-dd-yy) '
FCB EOT
*
MSG63 FCC 'SUNDAY '
FCB EOT
MSG64 FCC 'MONDAY '
FCB EOT
MSG65 FCC 'TUESDAY '
FCB EOT
MSG66 FCC 'WEDNESDAY '
FCB EOT
MSG67 FCC 'THURSDAY '
FCB EOT
MSG68 FCC 'FRIDAY '
FCB EOT
MSG69 FCC 'SATURDAY '
FCB EOT
MSG79 FCC 'The JULIAN Date is '
FCB EOT
HELPMSG:
FCC 'TIME JULIAN DATE'
FCB CR,CR
FCC 'HOUR [h] MONTH [m]'
FCB CR
FCC 'MINUTE [m] DAY [d]'
FCB CR
FCC ' YEAR [y]'
FCB CR
FCB EOT
******************************