View Single Post
Old 06-09-2012, 02:44 AM   PM User | #8
Krupski
Regular Coder

 
Krupski's Avatar
 
Join Date: Dec 2010
Location: United States of America
Posts: 502
Thanks: 39
Thanked 47 Times in 46 Posts
Krupski is on a distinguished road
Quote:
Originally Posted by felgall View Post
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..
Krupski is offline   Reply With Quote
Users who have thanked Krupski for this post:
IMayNeed (06-09-2012)