' Set Clock
' by Damien M. Jones
' Copyright ½ 1990 Damien M. Jones
' Version 2.2 (Reset-proof)
' Written for use with TODAY/ST (although can be used by itself)
' 05/12/90
'
Deffn Bcd(Byte%)=(Byte% Div 10)*16+(Byte% Mod 10)
'
Res%=Xbios(4) ! Current screen resolution
'
@Savecolor ! Save original colors.
If Res%=0 ! Low res, switch to medium.
  Void Xbios(5,L:-1,L:-1,W:1) ! Switch!
Endif
Setcolor 0,7,7,7 ! Background to white. (Standard ST colors)
Setcolor 1,7,0,0 ! Red
Setcolor 2,0,7,0 ! Green.
Setcolor 3,0,0,0 ! Text to black.
'
Dim Data%(2) ! 12 bytes, plenty of space for the clock.
Let Data%=Varptr(Data%(0)) ! Address of it.
'
Print Space$(18);"Set Clock 2.2  by Damien M. Jones  05/12/90" ! Credits!
Print Space$(13);"Copyright ½ 1990 Damien M. Jones. All Rights Reserved."
Print Space$(27);"This program is Freeware."
Print
'
@Read_clock
@Settime(T$,D$) ! Set it right away.
'
@Set_date ! Get possible new date.
'
@Settime("",D$) ! Set it.
'
@Set_time ! Get possible new time.
'
@Settime(T$,"") ! Set system clock from that data. This also sets the IKBD clock.
'
If Res%=0 ! Started in low res.
  Void Xbios(5,L:-1,L:-1,W:0) ! Switch back
  Void Xbios(6,L:Varptr(Q$)) ! Reset colors (may be necessary)
Endif
'
Edit
'
Procedure Settime(T$,D$) ! This is where the setting is done.
  Poke Data%,27 ! Code for set clock on IKBD
  If D$<>"" ! Date to set
    Poke Data%+1,@Bcd(Val(Right$(D$,2))) ! Year
    Poke Data%+2,@Bcd(Val(Left$(D$,2))) ! Month
    Poke Data%+3,@Bcd(Val(Mid$(D$,4,2))) ! Date
  Else
    Poke Data%+1,255 ! This tells the IKBD not to set this.
    Poke Data%+2,255 ! This tells the IKBD not to set this.
    Poke Data%+3,255 ! This tells the IKBD not to set this.
  Endif
  If T$<>"" ! Time to set
    Poke Data%+4,@Bcd(Val(Left$(T$,2))) ! Hour
    Poke Data%+5,@Bcd(Val(Mid$(T$,4,2))) ! Minutes
    Poke Data%+6,@Bcd(Val(Right$(T$,2))) ! Seconds
  Else
    Poke Data%+4,255 ! This tells the IKBD not to set this.
    Poke Data%+5,255 ! This tells the IKBD not to set this.
    Poke Data%+6,255 ! This tells the IKBD not to set this.
  Endif
  Void Xbios(25,W:7,L:Data%) ! Write all data to IKBD
  Pause 5 ! Short delay.
  Settime T$,D$ ! Set system time and date.
Return
'
Procedure Get_byte ! This is used by Read_clock
  Byte$=""
  If Peek(Data%+Byte%)<16 ! one-digit hex
    Byte$="0"
  Endif
  Byte$=Byte$+Hex$(Peek(Data%+Byte%))
  Inc Byte% ! Next byte.
Return
'
Procedure Savecolor
  Local X%
  Q$=""
  For X%=0 To 15
    Q$=Q$+Mki$(Xbios(7,X%,-1) And &H777)
  Next X%
Return
'
Procedure Read_clock
  Address%=0 ! Place to store the address of the clock packet.
  Machine_code$=Mki$(&H23C8)+Mkl$(*Address%)+Mki$(&H4E75) ! move.l a0,*A%   rts
  Vector%=Xbios(34)+20 ! Old clockvec location
  Old_vector%=Lpeek(Vector%) ! Old clockvec value
  Lpoke Vector%,Varptr(Machine_code$) ! New clock value
  Address%=0 ! Clear value (just to be sure).
  Out 4,&H1C ! Request a clock value
  Repeat     ! Wait for Interrupt
  Until Address%   ! (Until an address is present in A%
  Bmove Address%,Data%,6 ! Move it before it gets overwritten
  Lpoke Vector%,Old_vector% ! Restore old vector
  '
  D$="" ! Place to store date.
  T$="" ! Place to store time, also a temporary string.
  Byte%=0 ! Starting at byte 0.
  @Get_byte ! Read year.
  D$="/"+Byte$
  @Get_byte ! Read date.
  T$=Byte$+"/"
  @Get_byte
  D$=T$+Byte$+D$ ! Month, date, and year.
  T$="" ! Clear it again.
  @Get_byte ! Read hours.
  T$=Byte$+":"
  @Get_byte ! Read minutes.
  T$=T$+Byte$+":"
  @Get_byte ! Read seconds.
  T$=T$+Byte$
Return
'
Procedure Set_time
  Local I$,I%,Tim$,First!,Tim%
  Tim%=Timer ! Time routine was entered
  I$=T$  ! current time
  Tim$=I$   ! save that time, if they match, the time is NOT set
  Print Space$(31);"Set time:         ";
  First!=-1 ! First time through
  Repeat
    Print "f";Left$("",Len(I$));I$;"        ";"e";
    While (Not Inp?(2)) And First!=-1 ! Only update the first time.
      @Read_clock ! Update clock.
      If Timer-Tim%>800 ! More than four seconds have passed
        Time_out!=-1 ! Time out
      Endif
      Exit If Time_out! ! Time to exit loop
      If T$<>I$ ! Changed.
        Print "f";T$;"e";
        I$=T$
      Endif
    Wend
    Exit If Time_out! ! Time to exit
    I%=Inp(2) ! keyboard input
    If I%<>8 And I%<>13 And First!=-1 ! First time through, not a RETURN or BACKSPACE
      I$="" ! Clear input string
      Print "f        e"; ! Cursor off, back up, erase, back up, cursor on
    Endif
    First!=0 ! No longer the first time.
    If I%>47 And I%<58 And Len(I$)<8 ! digit, 0-9, room for it too
      I$=I$+Chr$(I%)
      Print Chr$(I%);
      If Len(I$)=2 Or Len(I$)=5
        Print ":";
        I$=I$+":" ! add a colon
      Endif
    Else
      If I%=8 And I$<>"" ! backspace
        Print "";
        If Right$(I$)=":" ! colon is the last character
          Print "";
          I$=Left$(I$,Len(I$)-1) ! backspace the colon
        Endif
        I$=Left$(I$,Len(I$)-1) ! backspace last number
      Else
        If I%=27 ! ESC
          Print Left$("",Len(I$));
          I$="" ! Clear
        Endif
      Endif
    Endif
  Until I%=13
  If I$<>Tim$ ! new time was entered
    T$=I$ ! Set it on return
  Else
    T$="" ! Don't set it.
  Endif
  Print "f" ! Cursor off.
Return
'
Procedure Set_date
  Local I$,I%,Tim$,First!,Tim%
  Tim%=Timer ! Time routine was entered
  I$=D$  ! current time
  Tim$=I$   ! save that time, if they match, the time is NOT set
  Print Space$(31);"Set Date:         ";
  First!=-1 ! First time through
  Repeat
    Print "f";Left$("",Len(I$));I$;"        ";"e";
    While (Not Inp?(2)) And First!=-1 ! Only update the first time.
      @Read_clock ! Update clock.
      If Timer-Tim%>800 ! More than four seconds have passed
        Time_out!=-1 ! Time out
      Endif
      Exit If Time_out! ! Time to exit loop
      If D$<>I$
        Print "f";D$;"e";
        I$=D$
      Endif
    Wend
    Exit If Time_out! ! Time to exit
    I%=Inp(2) ! keyboard input
    If I%<>8 And I%<>13 And First!=-1 ! First time through, not a RETURN or BACKSPACE
      I$="" ! Clear input string
      Print "f        e"; ! Cursor off, back up, erase, back up, cursor on
    Endif
    First!=0 ! No longer the first time.
    If I%>47 And I%<58 And Len(I$)<8 ! digit, 0-9, room for it too
      I$=I$+Chr$(I%)
      Print Chr$(I%);
      If Len(I$)=2 Or Len(I$)=5
        Print "/";
        I$=I$+"/" ! add a slash
      Endif
    Else
      If I%=8 And I$<>"" ! backspace
        Print "";
        If Right$(I$)="/" ! slash is the last character
          Print "";
          I$=Left$(I$,Len(I$)-1) ! backspace the slash
        Endif
        I$=Left$(I$,Len(I$)-1) ! backspace last number
      Else
        If I%=27 ! ESC
          Print Left$("",Len(I$));
          I$="" ! Clear
        Endif
      Endif
    Endif
  Until I%=13
  If I$<>Tim$ ! new date was entered
    D$=I$ ! Set it on return
  Else
    D$="" ! Don't set it.
  Endif
  Print "f" ! Cursor off.
Return
