|
Regular Coder
Join Date: Dec 2010
Location: United States of America
Posts: 502
Thanks: 39
Thanked 47 Times in 46 Posts
|
Quote:
Originally Posted by felgall
Also you are misusing parseInt in that code where you should be using Number() (which is really only needed around the (month+1) part if you are passing the month astext instead of as a number - you don't need to convert to base 10 anywhere in that function and so it doesn't need parseInt at all.
|
That code snippet is just a standard algorithm I use for my own stuff here. I have the same code in C, Intel ASM, Mototola ASM, GWBASIC and Javascript.
I do need parseInt because the algorithm depends on integer math and indeed fails if floating point numbers get involved.
If, for example, part of the algorithm does "1987 / 4", the result (496.75) would propagate through and produce an incorrect day of week. So I have to force JS to act as though all numbers are (INT).
For fun, make an array of day names, then run the JS code and plug in well known dates (Dec 7, 1941 - Sep 11, 2001, - etc...) and see what happens with and without "parseInt".
Edit:
How's this for some wild code?
Code:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; clockset.asm - sets smartclocks
; (c) 1996, 2010 roger a. krupski
; Thu 01/14/2010 17:31:45
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
clock equ $a000 ;clock memory mapped address
; offsets into clkbuf (smartclock data - see below)
centi equ 0 ;centiseconds offset
secs equ 1 ;seconds offset
mins equ 2 ;minutes offset
hours equ 3 ;hours offset
day equ 4 ;osc/rst/day offset
date equ 5 ;date offset
month equ 6 ;month offset
year equ 7 ;year offset
regbs equ $1000 ;register base
scsr equ regbs+$2e ;sci status reg
scdr equ regbs+$2f ;sci data reg
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; program starts here
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
org $2000 ;program in sram
jmp start ;jump around smartclock driver
; include m4859.asm ;driver for st micro
; include ds-1215.asm ;driver for smart-ram
include ds-1216.asm ;driver for smart-rom
start ldaa #' ' ;a = space
ldab #bufsiz ;buffer size
ldx #buffer ;point to input buffer
clrbuf staa 0,x ;erase buffer
inx ;bump pointer
decb ;count down
bne clrbuf ;do the rest
clrb ;b=0
stab curpos ;init cursor position to 0
ldx #msg1 ;point to prompt
jsr outstrg ;display it
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; this is the main user input loop
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
main jsr input ;read serial term
beq main ;wait for a key
cmpa #3 ;ctrl-c?
beq exit ;yes, exit
cmpa #27 ;escape?
bne main2 ;no, run program
exit ldx #msg3 ;point to abort message
jsr outstrg ;print it
swi ;ctrl-c received, exit!
main2 cmpa #13 ;c/r?
beq setit ;yes, set the clock!
cmpa #8 ;backspace?
beq do_bs ;yes, do it
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; here all controlling characters have been tested
; for. now we look for valid input such as spaces
; and numbers 0 thru 9. if not, we just ignore them.
; if matched, placed in the buffer.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
cmpa #' ' ;space?
beq char ;yes, add to buffer
cmpa #'0' ;number?
blo main ;no, ignore
cmpa #'9' ;number?
bhi main ;no, ignore
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; legal character found, write it to buffer
; legal character is either a space or 0 thru 9
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
char ldx #buffer ;point to buffer
ldab curpos ;get cursor position
cmpb #prlen ;at end?
bhs chrout ;at end, can't do anything
abx ;x points to current char
staa 0,x ;write char to buffer
incb ;move fwd 1 position
stab curpos ;update cursor position
jsr output ;echo char to term
chrout jmp main ;return to main loop
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; do backspace
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
do_bs ldx #buffer ;point to buffer
ldab curpos ;get cursor position
beq dobsout ;at beginning, can't do anything
decb ;backup 1 position
stab curpos ;update cursor position
abx ;x points -> current char in buffer
ldaa #' ' ;a = space
staa 0,x ;erase char in buffer
ldaa #8 ;load backspace
jsr output ;print backspace to term
ldaa #' ' ;load a space
jsr output ;erase char on term
ldaa #8 ;load backspace
jsr output ;backup cursor on term
dobsout jmp main ;return to main loop
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; done getting input, attempt to set the clock!
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
setit ldx #buffer+hro ;hour input
ldy #clkbuf+hours ;hour for clock
jsr conv ;convert 2 ascii to 1 packed bcd
cmpb #23 ;legal?
bhi badval ;no, abort!
ldx #buffer+mio ;minutes input
ldy #clkbuf+mins ;minutes for clock
jsr conv ;convert 2 ascii to 1 packed bcd
cmpb #59 ;legal?
bhi badval ;no, abort!
ldx #buffer+sco ;seconds input
ldy #clkbuf+secs ;seconds for clock
jsr conv ;convert 2 ascii to 1 packed bcd
cmpb #59 ;legal?
bhi badval ;no, abort!
ldy #clkbuf+centi ;centi for clock
clr 0,y ;default to zero
ldx #buffer+dao ;date input
ldy #clkbuf+date ;date for clock
jsr conv ;convert 2 ascii to 1 packed bcd
cmpb #1 ;legal?
blo badval ;no, abort
cmpb #31 ;legal?
bhi badval ;no, abort!
ldx #buffer+mno ;month input
ldy #clkbuf+month ;month for clock
jsr conv ;convert 2 ascii to 1 packed bcd
cmpb #1 ;legal?
blo badval ;no, abort
cmpb #12 ;legal?
bhi badval ;no, abort!
ldx #buffer+yro ;year input (last 2 digits)
ldy #clkbuf+year ;year for clock
jsr conv ;convert 2 ascii to 1 packed bcd
cmpb #99 ;legal?
bhi badval ;no, abort!
jsr dayweek ;get day of week (0=sunday)
andb #%00000111 ;strip unused bits
orab #%00010000 ;"or" in osc enable for dallas
stab clkbuf+day ;set osc, reset and d.o.w.
bra setclk ;set clock clock & swi
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; arrive here if invalid data (like "hour 90" is illegal)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
badval ldx #msg4 ;bad value
jsr outstrg ;print it
swi ;return to monitor
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; actually set the clock from the buffer here
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
setclk ldx #clkbuf ;point to buffer
ldy #clock ;point to clock chip
ldaa #0
jsr doclk ;write time to clock
ldx #verbuf ;point to verify buffer
ldy #clock ;point to clock chip
ldaa #1
jsr doclk ;read time back
ldx #msg2 ;"data verify...."
jsr outstrg ;print it
ldx #clkbuf ;point to write buffer
ldy #verbuf ;point to read buffer
ldab #8 ;bytes to verify
verf cpx #clkbuf+centi ;the "centiseconds" byte?
beq verf2 ;yes, skip test
cpx #clkbuf+day ;the "day" byte?
beq verf2 ;yes, skip test
ldaa 0,x ;get a byte
cmpa 0,y ;match?
bne fail ;yes
verf2 inx ;bump...
iny ;...pointers
decb ;count down
bne verf ;check rest
ldx #msg2s ;"...success!"
showit jsr outstrg ;print it
swi ;return to buffalo
fail ldx #msg2f ;"...failed!"
bra showit ;print it
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; convert 2 ascii bytes to one packed bcd number
; for the clock and also to one hex number
; for range validation.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
conv psha
pshx ;save registers
ldab 0,x ;get hi byte
cmpb #' ' ;space?
bne conv2 ;no, leave it
ldab #'0' ;yes, convert to zero
conv2 subb #'0' ;ascii -> decimal
aslb ;slide up to...
aslb
aslb
aslb ;...hi nybble
ldaa 1,x ;get lo byte
cmpa #' ' ;space?
bne conv3 ;no, leave it
ldaa #'0' ;yes, convert to zero
conv3 suba #'0' ;ascii -> decimal
aba ;a+b->a
tab ;a->b
stab 0,y ;store to clock buffer
bsr bcd2dec ;convert bcd to decimal
pulx
pula ;restore registers
rts ;return with decimal in b
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; packed bcd to decimal converter
;
; entry: b = bcd number 00-99
; exit : b = decimal equivalent
; example: entry b=$50, exit b=$32 (decimal 50)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
bcd2dec psha ;save a
pshb ;b on stack
lsrb ;shift hi...
lsrb ;...nibble down...
lsrb ;...to lower...
lsrb ;...nibble
ldaa #6 ;a=6
mul ;make conversion factor
negb ;make factor negative
pula ;restore b into a
aba ;add negative = subtract positive
tab ;a->b (result to b)
pula ;restore a
rts ;return to caller
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; here we find the day of week as 0 thru 6
; 0 thru 6 where 0=sunday, 1=monday, etc...
; using dr. christian zeller's congruence.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
dayweek ldx #clkbuf ;point to raw clock data
ldab month,x ;get bcd month
jsr bcd2dec ;convert to decimal
pshb ;month->stack
ldab date,x ;get bcd day
jsr bcd2dec ;convert to decimal
pshb ;day->stack
clra ;zero top of d
ldab year,x ;get bcd year
jsr bcd2dec ;convert to decimal
addd #2000 ;convert to full year
pshb
psha ;year->stack
pulx ;year->x
pulb ;day->b
pula ;month->a
;; fall through to zeller, then rts with data
;; stack offsets
offset 0
mn ds.w 1 ;temp month
dy ds.w 1 ;temp day
yr ds.w 1 ;temp year
tmp ds.w 1 ;intermediate results
ssiz equ *-mn ;storage size
astack ds.b 1 ;incoming month
bstack ds.b 1 ;incoming day / outgoing result
xstack ds.w 1 ;incoming year
ystack ds.w 1 ;just saved
;;;;;;;;;;;;;;;;;;;; code starts here ;;;;;;;;;;;;;;;;;;;;;;
zeller pshy
pshx
pshb ;(*) accb will get modified
psha ;save registers
;; allocate temp storage on the stack
ldab #ssiz ;storage size
alloc des ;reserve stack
decb ;more?
bne alloc ;yes do rest
tsy ;stack -> y (points to temp storage)
ldd #0 ;d=0
std tmp,y ;initialize accumulator
ldab astack,y ;get month lo byte
std mn,y ;store month (a=0)
ldab bstack,y ;get day lo byte
std dy,y ;store day (a=0)
ldd xstack,y ;get year
std yr,y ;store year (word)
;; this does "month 13 and 14" correction
ldd mn,y ;get month
cpd #2 ;jan or feb?
bhi zel2 ;no
addd #12 ;yes, add a year
std mn,y ;store updated month
ldd yr,y ;get year
subd #1 ;correct year (yr=yr-1)
std yr,y ;store updated year
zel2 ldd mn,y ;m
addd #1 ;(m+1)
ldaa #26 ;26
mul ;d=(m+1)*26
ldx #10 ;10
idiv ;x=((m+1)*26)/10
xgdx ;x->d
addd tmp,y ;do f1
std tmp,y ;store intermediate
ldd yr,y ;year
ldx #4 ;4
idiv ;x=(year/4)
xgdx ;x->d
addd tmp,y ;do f2
std tmp,y ;store intermediate
ldd yr,y ;year
ldx #100 ;100
idiv ;x=(year/100)
xgdx ;x->d
ldaa #6 ;a=6
mul ;d=6*(year/100)
addd tmp,y ;do f3
std tmp,y ;store intermediate
ldd yr,y ;year
ldx #400 ;400
idiv ;x=(year/400)
xgdx ;x->d
addd tmp,y ;do f4
std tmp,y ;store intermediate
ldd dy,y ;get day
addd tmp,y ;add intermediates
addd yr,y ;add year
subd #1 ;-1 (make sunday=0)
ldx #7 ;mod 7
idiv ;x=d/x, quotient to x, remainder to d
stab bstack,y ;(*) store result, return in accb
;; deallocate storage on the stack
ldab #ssiz ;storage size
dealloc ins ;deallocate
decb ;more?
bne dealloc ;yes do rest
;; restore registers
pula
pulb ;(*) day of week was placed here
pulx
puly ;restore registers
rts ;return with day of week in b
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; input (read) data from serial port
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
input ldaa scsr ;read status reg
anda #%00100000 ;check rdrf flag
beq input2 ;exit w/a=0 if no data
ldaa scdr ;read serial data
input2 rts ;return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; output (write) data to serial port
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
output psha ;save a
ldaa scsr ;read sci status register
coma ;invert bits
bita #%11000000 ;test tdre & tc
pula ;restore a
bne output ;sci busy, check again
staa scdr ;send character
rts
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; out string (print) string to serial port
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
outstrg ldaa 0,x ;get a char
beq outs2 ;done
bsr output ;send character out
inx ;increment buffer ptr
bra outstrg ;send next
outs2 rts ;return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; text messages for terminal
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
msg1 dc.b $0d,$0a
dc.b 'ENTER TIME & DATE:'
dc.b $0d,$0a
hro equ *-prompt ;offset
prompt dc.b 'HH ' ;hours prompt
mio equ *-prompt
dc.b 'MM ' ;minutes prompt
sco equ *-prompt
dc.b 'SS ' ;seconds prompt
mno equ *-prompt
dc.b 'MM ' ;month prompt
dao equ *-prompt
dc.b 'DD ' ;date prompt
yro equ *-prompt
dc.b 'YY' ;year prompt
prlen equ *-prompt ;prompt length (for input limit)
crlf dc.b $0d,$0a,0
msg2 dc.b $0d,$0a
dc.b 'READBACK ',0
msg2s dc.b 'CORRECT!'
dc.b $0d,$0a,0
msg2f dc.b 'FAILED!'
dc.b $0d,$0a,0
msg3 dc.b $0d,$0a
dc.b 'CANCELLED BY USER',0
msg4 dc.b $0d,$0a
dc.b 'DATA OUT OF RANGE'
dc.b $0d,$0a,0
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; buffers & vars in 'hc11 sram
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
org $100 ;evbu ram
buffer ds.b 32 ;incoming data buffer
bufsiz equ *-buffer ;size of buffer
curpos ds.b 1 ;cursor position
clkbuf ds.b 8 ;data to be fed to clock
verbuf ds.b 8 ;clock verify buffer
end
__________________
"Anything that is complex is not useful and anything that is useful is simple. This has been my whole life's motto." -- Mikhail T. Kalashnikov
Last edited by Krupski; 06-09-2012 at 02:48 AM..
|