home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 508.lha / IO_Expansion_Board / Time / Time.asm < prev   
Assembly Source File  |  1991-05-06  |  12KB  |  427 lines

  1. *****************************************************************************
  2. * Time.asm - ©1990,91 by The Puzzle Factory
  3. *          Real-Time Clock/Calendar driver.
  4. *
  5. *   Usage: 1> Time S=SET    ;Sets clock from system date.
  6. *          1> Time R=READ    ;Sets system date from clock.
  7. * History: 01/25/88 V0.50 Created by Jeff Lavin
  8. *          11/25/90 V0.51 Converted to new syntax
  9. *
  10. * [To all: Please don't forget to bump the revision numbers if you do *any*
  11. *          modifications at all.  -Jeff]
  12. *
  13. * Notes:
  14. * There are several places in this program where small delays that are needed
  15. * by the clock chip are created by the use of one or two 'NOP' instructions.
  16. * These delays are calculated for a 7Mhz 68000 and may not work on a faster
  17. * or different processor.  If you experience problems, try doubling the
  18. * number of 'NOPs'.  I realize that this isn't good code, but I don't feel
  19. * that the extra work is warranted in this particular case.  Feel free to add
  20. * any improvements that you like.
  21. *
  22. * When setting the clock from system time, you would enter the date and time
  23. * with the 'DATE' command, and then type 'Time SET'.  Be aware that when
  24. * setting the clock, seconds are considered to be zero.  In order to get the
  25. * most accurate time, set the clock just as system time passes the minute so
  26. * that seconds really are zero.
  27. *
  28. *****************************************************************************
  29.  
  30. ;Set Tabs    |    |    |    |
  31.  
  32.     exeobj
  33.     objfile    'ram:Time'
  34.     macfile 'Includes:IOexp.i'    ;The One & Only include file
  35.  
  36. *  CLOCK / CALENDAR DRIVER PROGRAM
  37. *  for OKI MSM5832 MICROPROCESSOR
  38. *    Real-Time Clock / Calendar
  39. *
  40. * Copyright ©1990,91 The Puzzle Factory - All rights reserved
  41. * This program may not be used commercially without prior
  42. * written permission from the author.
  43. *
  44. * The clock/calendar is driven by a VIA.
  45. * The port bit assignments are as follows:
  46. *
  47. *   PORT A bits      PORT B bits
  48. * 7 6 5 4 3 2 1 0    7 6 5 4 3 2 1 0
  49. * ---------------------------------
  50. * D D D D A A A A          T|A|R|W|H
  51. * 3 2 1 0 3 2 1 0          E|D|E|R|O
  52. *          S|J|A|I|L
  53. *          T   D|T|D
  54. *            E
  55. *
  56. *              ________________________________________
  57. *             |                 |
  58. *  HOLD  _____|                 |_____
  59. *                ____________________________________
  60. *               |                   |
  61. *  READ  _______|                   |_______
  62. *        ________  _________  _________  _________  _________
  63. *                \/     \/         \/        \/
  64. *  A0-A3 ________/\_________/\_________/\_________/\_________
  65. *        __________  _________  _________  _________  _______
  66. *  Data Out        \/      \/         \/          \/
  67. *  D0-D3 __________/\_________/\_________/\_________/\_______
  68. *         R E A D   C Y C L E
  69. *              ________________________________________
  70. *             |                 |
  71. *  HOLD  _____|                 |_____
  72. *        ________  _________  _________  _________  _________
  73. *                \/     \/         \/        \/
  74. *  A0-A3 ________/\_________/\_________/\_________/\_________
  75. *        ________  _________  _________  _________  _________
  76. *  Data In       \/     \/         \/        \/
  77. *  D0-D3 ________/\_________/\_________/\_________/\_________
  78. *     _____      _____      _____
  79. *    /     \    /     \    /      \
  80. *  WRITE __________/       \__/       \__/       \___________
  81. *        W R I T E   C Y C L E
  82. *
  83. *
  84. * The registers assignments are:
  85. *
  86. * REG: $00 $01 $02 $03 $04 $05 $06 $07 $08 $09 $0A $0B $0C
  87. * --------------------------------------------------------
  88. * CNT: 01S 10S 01M 10M 01H 10H DoW D01 D10 M01 M10 Y01 Y10
  89. *
  90. *       5   3   6    2   9    8   2   4   2   1   0   9   8
  91. *
  92. * This example would be:  09:26:35 TUESDAY JAN 24 1989
  93. *
  94. * Bit 7 of 10H is: 0 = 12 hr format, 1 = 24 hr format
  95.  
  96. dat_Format    equ    $0C    ;Arp DateTime Structure
  97. dat_Flags    equ    $0D
  98. dat_StrDay    equ    $0E
  99. dat_StrDate    equ    $12
  100. dat_StrTime    equ    $16
  101. dat_SIZEOF    equ    $1A
  102.  
  103. LEN_DATSTRING    equ    10
  104. FORMAT_USA    equ    2
  105. DTB_FUTURE    equ    2
  106.  
  107. SECONDS_PER_DAY    equ    1440
  108. SECONDS_PER_MINUTE    equ    60
  109.  
  110. *** Begin Mainline
  111.  
  112. Time    movem.l    d0/a0,-(sp)
  113.     lea    (ArpName,pc),a1    ;Open arp.library
  114.     moveq    #34,d0    ;Version 34 or later
  115.     movea.l    (SysBase).w,a6
  116.     SYS    OpenLibrary
  117.     tst.l    d0
  118.     bne.b    OK_Go    ;Got arp, run program
  119.     lea    (DosName,pc),a1    ;Else, open dos.library
  120.     SYS    OpenLibrary
  121.     tst.l    d0
  122.     beq.b    1$
  123.     movea.l    d0,a6
  124.     SYS    Output    ; and get output filehandle
  125.     move.l    d0,d1
  126.     beq.b    1$
  127.     move.l    #alibmsg,d2
  128.     moveq    #aliblng,d3
  129.     SYS    Write    ; so we can complain
  130. 1$    addq.w    #8,SP    ; and exit.
  131.     rts
  132.  
  133. DosName    cstr    'dos.library'
  134. alibmsg    db    'you need '
  135. ArpName    db    'arp.library',0,0
  136.     db    ' V34+',10
  137. aliblng    equ    *-alibmsg
  138.  
  139. OK_Go    movea.l    d0,a6    ;ArpBase
  140.     lea    (DT),a4    ;Setup BSS base register
  141.     lea    (VIA_Base),a5    ;Setup I/O base register
  142.     movem.l    (sp)+,d0/a0
  143.     lea    (Help.msg,pc),a1
  144.     lea    (ArgArray-DT,a4),a2
  145.     lea    (Template,pc),a3
  146.     SYS    GADS
  147.     cmpi.w    #1,d0    ;Count of args, must = 1
  148.     bne.b    1$    ;Instruct & quit
  149.  
  150.     lea    (DateTime-DT,a4),a3
  151.     move.b    #FORMAT_USA,(dat_Format,a3)
  152.     bset    #DTB_FUTURE,(dat_Flags,a3)
  153.     move.l    #DayStr,(dat_StrDay,a3)
  154.     move.l    #DateStr,(dat_StrDate,a3)
  155.     move.l    #TimeStr,(dat_StrTime,a3)
  156.  
  157.     tst.l    (Arg2-DT,a4)    ;Is 'SET' argument on?
  158.     bmi.b    SetTime    ;Yes, set clock from SysTime
  159.     tst.l    (Arg1-DT,a4)    ;Is 'READ' argument on?
  160.     bmi    ReadTime    ;Yes, read clock to SysTime
  161. 1$    bra    ArgErr    ;Must be R or S, instruct & quit
  162.  
  163. *** Set Hardware Clock from System Time
  164.  
  165. SetTime    move.l    a3,d1    ;Ptr to DateTime structure
  166.     SYS    DateStamp    ;Get system time
  167.     movea.l    a3,a0
  168.     SYS    StamptoStr
  169.     tst.l    d0
  170.     bne    DateErr    ;Couldn't read DateStamp, exit
  171.  
  172.     move.b    #$FF,(DDRB,a5)    ;Set to all outputs
  173.     move.b    #$FF,(DDRA,a5)    ;Set to all outputs
  174.     move.b    #1,(ORB,a5)    ;Set HOLD high
  175.     bsr    Wait    ;150 usec HOLD setup time
  176.  
  177.     lea    (DateStr-DT,a4),a0 ;Date from StampToString
  178.     lea    (Str_order,pc),a1    ;Order of string bytes to read
  179.     lea    (Reg_order,pc),a2    ;Order of registers to write
  180.     moveq    #0,d2    ;Index
  181.     moveq    #0,d3    ;Index
  182. SetLoop    move.b    (0,a1,d3.w),d2    ;Which string byte to read
  183.     move.b    (0,a0,d2.w),d0    ;Get date/time data
  184.     lsl.b    #4,d0    ;Shift data to upper nibble
  185.     move.b    (0,a2,d3.w),d1    ;Which register to write
  186.     or.b    d1,d0    ;Combine register addr in lower nibble
  187.     move.b    d0,(ORA,a5)    ;Send the whole mess to the clock
  188.     nop        ;Data setup time
  189.     nop
  190.     move.b    #3,(ORB,a5)    ;Raise WRITE line
  191.     nop        ;WRITE pulse width
  192.     move.b    #1,(ORB,a5)    ;Lower WRITE line
  193.  
  194.     addq.w    #1,d3
  195.     cmpi.w    #12,d3
  196.     bhs.b    1$
  197.     cmpi.w    #6,d3    ;If <> 6, do next whatever
  198.     bne.b    SetLoop    ;Else, we finished the date
  199.     lea    (TimeStr-DT,a4),a0 ;So start on the time
  200.     bset.b    #3,(0,a0)    ;Mark 10 Hour for 24 hr mode
  201.     bra.b    SetLoop
  202.  
  203. 1$    lea    (Day_index,pc),a3    ;Index into table
  204.     lea    (Day_table,pc),a2    ;Table of day strings
  205.     moveq    #0,d2    ;Loop Counter & Day of Week for clock
  206. 2$    lea    (DayStr-DT,a4),a0    ;Ptr to Day of Week string (system)
  207.     moveq    #0,d1
  208.     move.b    (0,a3,d2.w),d1    ;Offset to string
  209.     lea    (0,a2,d1.w),a1    ;Ptr to Day of Week string (table)
  210.     SYS    Strcmp
  211.     beq.b    3$
  212.     addq.w    #1,d2
  213.     cmpi.w    #7,d2
  214.     blo.b    2$
  215.     bra    DateErr    ;Can't match system string
  216.  
  217. 3$    lsl.b    #4,d2    ;Shift data to upper nibble
  218.     ori.b    #6,d2    ;Combine register addr in lower nibble
  219.     move.b    d2,(ORA,a5)    ;Send the whole mess to the clock
  220.     nop        ;Data setup time
  221.     nop
  222.     move.b    #3,(ORB,a5)    ;Raise WRITE line
  223.     nop        ;WRITE pulse width
  224.     move.b    #1,(ORB,a5)    ;Lower WRITE line
  225.     nop        ;DATA hold time
  226.     move.b    #0,(ORB,a5)    ;Reset HOLD low & Fall thru
  227.  
  228. *** Read Hardware Clock and Set System Time
  229.  
  230. ReadTime    move.b    #$FF,(DDRB,a5)    ;Set to all outputs
  231.     move.b    #$0F,(DDRA,a5)    ;Hi-nibble=inputs, lo-nibble=outputs
  232.     move.b    #1,(ORB,a5)    ;Set HOLD high
  233.     bsr    Wait    ;150 usec HOLD setup time
  234.     move.b    #5,(ORB,a5)    ;Set for READ mode
  235.  
  236.     lea    (DateStr-DT,a4),a0 ;Date for StrDate
  237.     lea    (TimeStr-DT,a4),a1 ;Time for StrTime
  238.     move.b    #'-',(2,a0)    ;Initialize separators
  239.     move.b    #'-',(5,a0)
  240.     move.b    #':',(2,a1)
  241.     move.b    #':',(5,a1)
  242.  
  243.     lea    (Str_order,pc),a1    ;Order of string bytes to write
  244.     lea    (Reg_order,pc),a2    ;Order of registers to read
  245.     lea    (DataMask,pc),a3    ;Mask for unwanted bits
  246.     moveq    #0,d1    ;Index
  247.     moveq    #0,d2    ;Index
  248.  
  249. ReadLoop    move.b    (0,a2,d2.w),(ORA,a5) ;Get next register
  250.     nop        ;READ access time
  251.     moveq    #0,d0
  252.     move.b    (ORA,a5),d0    ;Get clock data
  253.     lsr.b    #4,d0    ;Shift into lower nibble
  254.     and.b    (0,a3,d2.w),d0    ;Mask off unwanted info
  255.     addi.b    #$30,d0    ;Make ASCII
  256.     move.b    (0,a1,d2.w),d1    ;Which string byte to write
  257.     move.b    d0,(0,a0,d1.w)    ;Put clock data in date/time string
  258.  
  259.     addq.w    #1,d2
  260.     cmpi.w    #12,d2
  261.     bhs.b    1$
  262.     cmpi.w    #6,d2    ;If <> 6, do next whatever
  263.     bne.b    ReadLoop    ;Else, we finished the date
  264.     lea    (TimeStr-DT,a4),a0 ;So start on the time
  265.     bra.b    ReadLoop
  266.  
  267. 1$    move.b    #6,(ORA,a5)    ;Day of Week register
  268.     nop        ;READ access time
  269.     moveq    #0,d0
  270.     move.b    (ORA,a5),d0    ;Get clock data
  271.     move.b    #0,(ORB,a5)    ;Reset HOLD low
  272.     lsr.b    #4,d0    ;Shift into lower nibble
  273.     andi.w    #%00000111,d0    ;Mask off unwanted info
  274.  
  275.     lea    (DateTime-DT,a4),a3 ;Ptr to DateTime structure
  276.     movea.l    (dat_StrDay,a3),a2
  277.     lea    (Day_table,pc),a1    ;Table of day strings
  278.     lea    (Day_index,pc),a0    ;Index into table
  279.     moveq    #0,d1
  280.     move.b    (0,a0,d0.w),d1    ;Where string[D0] starts
  281. 2$    move.b    (0,a1,d1.w),(a2)+    ;Move Day of Week string to target
  282.     addq.l    #1,a1
  283.     bne.b    2$
  284.  
  285.     tst.l    (Arg2-DT,a4)    ;Is 'SET' argument on?
  286.     bmi.b    3$    ;Yes, don't set SysTime, just print
  287.  
  288.     movea.l    a3,a0
  289.     SYS    StrtoStamp    ;Convert clock strings
  290.     bne    ConvErr    ;Can't convert DateStamp
  291.  
  292. * Formula:  (((ds_Days * 1440) + ds_Minute) * 60) + (ds_Tick / 50)
  293.  
  294.     move.l    (ds_Days,a3),d0    ;# of Days since 01/01/78
  295.     mulu.w    #SECONDS_PER_DAY,d0
  296.     add.l    (ds_Minute,a3),d0    ;# of Minutes since midnight
  297.     move.l    d0,d1
  298.     mulu.w    #SECONDS_PER_MINUTE,d1 ;Lower 16 bits
  299.     swap    d0
  300.     mulu.w    #SECONDS_PER_MINUTE,d0 ;Upper 16 bits
  301.     swap    d0
  302.     add.l    d1,d0    ;Add 'em
  303.     move.l    (ds_Tick,a3),d1    ;# of Seconds since midnight
  304.     divu.w    #TICKS_PER_SECOND,d1
  305.     ext.l    d1
  306.     add.l    d1,d0    ;# of seconds since 01/01/78
  307.     bsr.b    SetSysTime
  308.     lea    (Read.msg,pc),a0    ;Print "System Time set to..."
  309.     bra.b    4$
  310.  
  311. 3$    lea    (Set.msg,pc),a0    ;Print "Clock Time set to..."
  312. 4$    lea    (PArgs-DT,a4),a1
  313.     movea.l    a1,a2
  314.     lea    (dat_StrDay,a3),a3
  315.     move.l    (a3)+,(a2)+    ;Move ptrs to strings for Printf
  316.     move.l    (a3)+,(a2)+
  317.     move.l    (a3)+,(a2)+
  318.     moveq    #RETURN_OK,d3
  319.     moveq    #0,d2
  320.     bra    Exit
  321.  
  322. *** Subroutines
  323.  
  324. Wait    moveq    #40,d1    ;Approx. 150 usec
  325. 1$    subq.l    #1,d1
  326.     bpl.b    1$    ;So it's a cpu hog - how often do
  327.     rts        ; you read/set the clock, anyway?
  328.  
  329. SetSysTime    move.l    a6,-(sp)
  330.     movea.l    (SysBase).w,a6
  331.     moveq    #0,d2
  332.     move.l    d0,d3    ;[D0] = # of seconds
  333.     suba.w    #IOTV_SIZE,sp
  334.     movea.l    a6,a0
  335.     movea.l    (ThisTask,a0),a0
  336.     lea    (pr_MsgPort,a0),a0
  337.     move.l    a0,(MN_REPLYPORT,sp)
  338.     lea    (TimerName,pc),a0
  339.     move.l    #0,d0
  340.     movea.l    sp,a1
  341.     moveq    #0,d1
  342.     SYS    OpenDevice
  343.     tst.l    d0
  344.     bne.b    1$
  345.     move.w    #TR_SETSYSTIME,(IO_COMMAND,sp)
  346.     clr.l    (IOTV_TIME+TV_MICRO,sp)
  347.     move.l    d3,(IOTV_TIME+TV_SECS,sp)
  348.     movea.l    sp,a1
  349.     SYS    DoIO
  350.     movea.l    sp,a1
  351.     SYS    CloseDevice
  352. 1$    adda.w    #IOTV_SIZE,sp
  353.     movea.l    (sp)+,a6
  354.     rts
  355.  
  356. TimerName    cstr    'timer.device'
  357.     even
  358.  
  359. ArgErr    lea    (Help.msg,pc),a0    ;Print instructions
  360.     moveq    #RETURN_WARN,d3
  361.     moveq    #ERROR_LINE_TOO_LONG,d2
  362.     bra.b    Quit
  363.  
  364. MemErr    lea    (NoMem.msg,pc),a0    ;Print "No memory"
  365.     moveq    #RETURN_FAIL,d3
  366.     moveq    #ERROR_NO_FREE_STORE,d2
  367.     bra.b    Quit
  368.  
  369. ConvErr    lea    (Stamp1.msg,pc),a0 ;Print "Can't convert to DateStamp"
  370.     bra.b    Err.1
  371.  
  372. DateErr    lea    (Stamp2.msg,pc),a0 ;Print "Can't read system time"
  373. Err.1    moveq    #RETURN_FAIL,d3
  374.     move.l    #200,d2    ;Internal error
  375.  
  376. Quit    lea    (NULLBYT,pc),a1    ;Null arg
  377. Exit    SYS    Printf    ;Write message
  378.     move.l    d3,d0    ;D0 = ReturnCode, D2 = Fault
  379.     SYS    ArpExit
  380.  
  381. Help.msg    db    'Time V1.0 - ©1990,91 by The Puzzle Factory',10
  382.     db    'Time S/SET  sets clock from system date.',10
  383.     db    'Time R/READ sets system date from clock.',10
  384. NULLBYT    db    0
  385.  
  386. Template    cstr    'R=READ/S,S=SET/S'
  387.  
  388. NoMem.msg    cstr    'Can''t allocate memory.',10
  389. Stamp1.msg    cstr    'Can''t convert to DateStamp.',10
  390. Stamp2.msg    cstr    'Can''t read system time.',10
  391.  
  392. Set.msg    cstr    'Clock Time set to: %s %s %s',10
  393. Read.msg    cstr    'System Time set to: %s %s %s',10
  394.  
  395. ;        M10 M01 D10 D01 Y10 Y01 10H 01H 10M 01M 10S 01S
  396. Reg_order    db    $0A,$09,$08,$07,$0C,$0B,$05,$04,$03,$02,$01,$00
  397. DataMask    db    $01,$0F,$03,$0F,$0F,$0F,$03,$0F,$07,$0F,$07,$0F 
  398. Str_order    db    $00,$01,$03,$04,$06,$07,$00,$01,$03,$04,$06,$07
  399.  
  400. Day_index    db    Day0-Day0,Day1-Day0,Day2-Day0,Day3-Day0
  401.     db    Day4-Day0,Day5-Day0,Day6-Day0
  402. Day_table
  403. Day0    cstr    'Sunday'
  404. Day1    cstr    'Monday'
  405. Day2    cstr    'Tuesday'
  406. Day3    cstr    'Wednesday'
  407. Day4    cstr    'Thursday'
  408. Day5    cstr    'Friday'
  409. Day6    cstr    'Saturday'
  410.  
  411. DT
  412. ArgArray
  413. Arg1    dx.l    1
  414. Arg2    dx.l    1
  415.  
  416. PArgs    dx.l    3
  417.  
  418. DateTime    dx.b    dat_SIZEOF
  419. DayStr    dx.b    LEN_DATSTRING
  420. DateStr    dx.b    LEN_DATSTRING
  421. TimeStr    dx.b    LEN_DATSTRING
  422.  
  423.     end
  424.