'===========================================================================
' Subject: CONTINUALLY DISPLAY ACTUAL TIME    Date: 07-21-96 (22:02)       
'  Author: Egbert Zijlema                     Code: PB                     
'  Origin: E.Zijlema@uni4nn.iaf.nl          Packet: DATETIME.ABC
'===========================================================================
' SHOWTIME.BAS ---- continuatedly displays the actual time
' Author          : Egbert Zijlema (E.Zijlema@uni4nn.iaf.nl)
' Date            : July 21, 1996
' Language        : Power Basic 3.2
' Copyright status: Public Domain

' Info:
' Most of the time a program is just waiting for user activity
' (e.g. keyboard input). These "pauses" are the most excellent
' moments to display the actual time. For instance at the menu bar.
' There is only 1 restriction: the Basic commands LOCATE and/or PRINT
' should ALWAYS serve the user, so your program must write (POKE) the
' time information directly to video memory.

' In this demo a sample menu lets you toggle between different formats:
' hh:mm:ss (the default TIME$)
' hh:mm (including a blinking colon)
' 12/24 hrs system, adding AM or PM for 12 hrs

' For computers with vga card there is an extra font to display
' the time in 'digital' form. These font (earlier released as
' "LOADFONT.BAS") includes the characters 0 - 9, A, P and M. They
' will temporaryly replace the characters 224 throug 238 of the
' default ASCII set. It is to be restored while quitting.
' ---------------------------------------------------------------------

DEFINT A - Z

%NO = 0 : %YES = NOT %NO           ' equates true/false (0/-1)

%AX = 1 : %BX = 2 : %CX = 3        ' equates for ...
%DX = 4 : %BP = 7 : %ES = 9        ' ... registers

TYPE CLOCKFLAGS
  twelve AS INTEGER                ' 12 hrs clock
  secs AS INTEGER                  ' show seconds
  font AS INTEGER                  ' use special font
END TYPE

TYPE FLAGS
  mono AS INTEGER                  ' monochrome screen
  vga AS INTEGER                   ' ega/vga card present
END TYPE

DIM clok AS SHARED CLOCKFLAGS
DIM flg AS SHARED FLAGS
DIM VideoAddress AS SHARED INTEGER

IF (pbvScrnCard AND 1) = 0 THEN    ' test card type
  VideoAddress = &HB800            ' color card
ELSE
  VideoAddress = &HB000            ' monochrome
  flg.mono = %YES
END IF

IF BIT(pbvScrnCard, 4) THEN        ' is it a vga-card as well?
  LoadFont                         ' load special chars
  flg.vga = %YES                   ' vga modifications done!
END IF

SUB LoadFont
  cred$ = CHR$(126, 129, 189, 165, 161, 165, 189, 129, 126)
  phon$ = CHR$(  0,   0,   0, 126, 255, 153,  60, 126, 126)
  zero$ = CHR$( 56, 198, 198, 198,   0, 198, 198, 198,  56)
  one$  = CHR$( 24,  24,  24,  24,   0,  24,  24,  24,  24)
  two$  = CHR$( 56, 198,   6,   6,  56, 192, 192, 192,  62)
  thre$ = CHR$( 56, 198,   6,   6,  56,   6,   6, 198,  56)
  four$ = CHR$(198, 198, 198, 198,  56,   6,   6,   6,   6)
  five$ = CHR$( 62, 192, 192, 192,  56,   6,   6, 198,  56)
  six$  = CHR$(192, 192, 192, 192,  56, 198, 198, 198,  56)
  sevn$ = CHR$(248,   6,   6,   6,   0,   6,   6,   6,   6)
  eigt$ = CHR$( 56, 198, 198, 198,  56, 198, 198, 198,  56)
  nine$ = CHR$( 56, 198, 198, 198,  56,   6,   6, 198,  56)
  a$    = CHR$( 56, 198, 198, 198,  56, 198, 198, 198, 198)
  p$    = CHR$( 56, 198, 198, 198,  56, 192, 192, 192, 192)
  m$    = CHR$(126, 219, 219, 219,   0, 219, 219, 195, 195)

  start$    = STRING$(3, 0)    ' align top
  tail$     = STRING$(4, 0)    ' align tail
  between$  = STRING$(7, 0)    ' align prev. and next char

  ' NOTE: if the characters don't bottom align versus default
  '       font characters (e.g. the colon) then unmark the next line:

  ' SWAP start$, tail$

  pattern$  = start$ + cred$ + between$ + phon$ + between$ + zero$ + _
              between$ + one$ + between$ + two$ + between$ + thre$ + _
              between$ + four$ + between$ + five$ + between$ + six$ + _
              between$ + sevn$ + between$ + eigt$ + between$ + nine$ + _
              between$ + a$ + between$ + p$ + between$ + m$ + tail$

  REG %AX, &H1100               ' function
  REG %BX, 16 * 256             ' 16 bytes per char in BH
  REG %CX, 15                   ' number of characters
  REG %DX, 224                  ' first char in ASCII-set to modify
  REG %ES, STRSEG(pattern$)
  REG %BP, STRPTR(pattern$)
  CALL INTERRUPT &H10
  REG %AX, &H1103               ' function
  REG %BX, 0
  CALL INTERRUPT &H10
END SUB

' Trim all spaces from both ends of a string
FUNCTION TRIM(BYVAL text AS STRING) AS STRING
  FUNCTION = LTRIM$(RTRIM$(text))
END FUNCTION

FUNCTION TimeToDisplay AS STRING
  temp$ = TIME$
  IF NOT clok.secs THEN temp$ = LEFT$(temp$, 5)    ' skip seconds
  hour = VAL(LEFT$(temp$, 2))
  extension$ = SPACE$(3)

  IF clok.twelve THEN
    SELECT CASE hour
      CASE => 12
        IF hour > 12 THEN DECR hour, 12
        extension$ = " PM"
      CASE ELSE
        IF hour = 0 THEN hour = 12
        extension$ = " AM"
    END SELECT
  END IF

  temp$ = TRIM(STR$(hour)) + MID$(temp$, 3) + extension$
  temp$ = temp$ + SPACE$(11 - LEN(temp$) )  ' fixed length = 11 chars

  IF clok.font THEN
    FOR count = 48 TO 57
      REPLACE CHR$(count) WITH CHR$(count + 178) IN temp$
    NEXT
    REPLACE CHR$(65) WITH CHR$(236) IN temp$
    REPLACE CHR$(80) WITH CHR$(237) IN temp$
    REPLACE CHR$(77) WITH CHR$(238) IN temp$
  END IF

  FUNCTION = temp$
END FUNCTION

SUB TimeInfo
  STATIC colon
  IF flg.mono THEN
    attri = 112                               ' black on white
  ELSE
    attri = 121                               ' blue on white
  END IF

  Info$ = TimeToDisplay
  IF colon = %NO AND clok.secs = %NO THEN
    REPLACE ":" WITH CHR$(32) IN Info$
    colon = %YES
  ELSE
    colon = %NO
  END IF

  NextChar = 1

  DEF SEG = VideoAddress
  FOR offset = 102 TO 122 STEP 2               ' 11 characters + 11 colors
    character = ASC(MID$(Info$, NextChar, 1))
    POKE offset, character
    POKE offset + 1, attri
    INCR NextChar
  NEXT
  DEF SEG
END SUB

FUNCTION GetKey
  STATIC lastTime$

  DO

    IF TIME$ <> lastTime$ THEN                 ' every second
      lastTime$ = TIME$
      TimeInfo
    END IF

  LOOP UNTIL INSTAT

  FUNCTION = CVI( INKEY$ + CHR$(0) )
END FUNCTION

SUB DemoMenu

  ' menu text
  COLOR 7, 0
  IF flg.vga THEN
    LOCATE 3, 4
    PRINT "F1  = toggle fonts"
  END IF
  LOCATE 4, 4 : PRINT "F2  = toggle seconds"
  LOCATE 5, 4 : PRINT "F3  = toggle 12/24 hrs"
  LOCATE 6, 4 : PRINT "Esc = end of this demo"

  DO
    KeyIn = GetKey
    SELECT CASE KeyIn
      CASE 27
        IF flg.vga THEN SCREEN 0, 0, 0, 0   ' restore default font
        CLS
        SYSTEM
      CASE 59 * 256                         ' F1
        IF NOT flg.vga THEN EXIT SELECT
        IF clok.font THEN clok.font = %NO ELSE clok.font = %YES
      CASE 60 * 256                         ' F2
        IF clok.secs THEN clok.secs = %NO ELSE clok.secs = %YES
      CASE 61 * 256                         ' F3
        IF clok.twelve THEN clok.twelve = %NO ELSE clok.twelve = %YES
    END SELECT
  LOOP
END SUB


' demo main

CLS
  COLOR 0, 7
  LOCATE 1, 1 : PRINT SPACE$(80);         ' dummy menu bar
  LOCATE 1, 4 : PRINT "Sample Menu Bar"

  clok.secs = %YES                        ' start with default TIME$
  CALL DemoMenu
END
