home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / UTILITY / SYSTEM / MMCLK12.ZIP / INIT.ASM < prev    next >
Encoding:
Assembly Source File  |  1990-06-23  |  8.8 KB  |  370 lines

  1.     include    mmclock.mac
  2.     title    MM58167A clock driver init -- Copyright 1990 Wales
  3.  
  4. ; ======================================================================
  5. ;
  6. ; MM58167A clock/calendar driver initialization.
  7. ; (C) Copyright 1990 Richard B. Wales.  All Rights Reserved.
  8. ;
  9. ; Global variables:
  10. ;
  11. ;    None.
  12. ;
  13. ; Global routines:
  14. ;
  15. ;    DriverInit
  16. ;        Initializes the driver.
  17.  
  18. ; ======================================================================
  19. ;
  20. ; Start of the initialization code.  Everything from this point onward
  21. ; can be thrown away once the driver has been initialized.
  22.  
  23. StartInit equ    $
  24.  
  25. ; ======================================================================
  26. ;
  27. ; Various character strings.
  28.  
  29. CR    equ    0Dh
  30. LF    equ    0Ah
  31. TAB    equ    09h
  32.  
  33. Banner       db    CR, LF
  34.        db    '╔═══════════════════════════════════════════════╗', CR, LF
  35.        db    '║ MM58167A Clock Driver -- Version 1.20 (06/90) ║', CR, LF
  36.        db    '║      (C) Copyright 1990 Richard B. Wales      ║', CR, LF
  37.        db    '║ (213)826-0893     Internet: wales@CS.UCLA.EDU ║', CR, LF
  38.        db    '$'
  39.  
  40. ClkFound   db    '║     Real-time clock found; I/O port '
  41. ClkAddr       db    'XXXXh     ║', CR, LF
  42.        db    '║  Current date/time:  '
  43. CurDay       db    'XX '
  44. CurMon     db    'XXX '
  45. CurYear       db    'XXXX '
  46. CurHour       db    'XX:'
  47. CurMin       db    'XX:'
  48. CurSec       db    'XX.'
  49. CurHSec       db    'XX  ║', CR, LF, '$'
  50. Windup       db    '╚═══════════════════════════════════════════════╝'
  51.        db    CR, LF, CR, LF, '$'
  52.  
  53. NoClkFound db    '║ Clock not found!   ** DRIVER NOT INSTALLED ** ║'
  54.        db    CR, LF, '$'
  55.  
  56. ; ======================================================================
  57. ;
  58. ; Stuff for identifying the month.
  59. ; Note that February in this table has 29 days (as for leap year).
  60. ; Before trying to identify the month, any date in March or later
  61. ; in a non-leap year is incremented by one; hence, this works.
  62.  
  63. MonLen  dw    31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
  64. MonNam    db    'Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec '
  65.  
  66. ; ======================================================================
  67. ;
  68. ; Buffer for reading the initial clock value.
  69.  
  70. buffer    db    6 dup (?)
  71.  
  72. ; ======================================================================
  73. ;
  74. ; Hex-to-ASCII conversion table.
  75.  
  76. hex2asc    db    '0123456789ABCDEF'
  77.  
  78. ; ======================================================================
  79. ;
  80. ; Port list -- used when a port number is specified via an argument.
  81.  
  82. ThePort    dw    ?, 0
  83.  
  84. ; ======================================================================
  85. ;
  86. ; Global symbols.
  87.  
  88.     public    DriverInit
  89.  
  90. ; ======================================================================
  91. ;
  92. ; External routines called.
  93.  
  94.     extrn    LookForClock:proc, ClkToBuf:proc, SetBIOS:proc
  95.  
  96. ; ======================================================================
  97. ;
  98. ; Binary-to-BCD conversion table.
  99.  
  100.     extrn    bin2bcd:byte
  101.  
  102. ; ======================================================================
  103. ;
  104. ; DriverInit
  105. ;
  106. ;    Announces the driver and looks for the clock.
  107. ;
  108. ;    Arguments:
  109. ;
  110. ;        DS:SI    Text of the DRIVER= line in the CONFIG.SYS file
  111. ;            (starting with the character after the "=").
  112. ;
  113. ;    Returned values:
  114. ;
  115. ;        CX    Offset (relative to CS) of the first byte that
  116. ;            does not need to be saved in the driver.  If the
  117. ;            clock was not found, CX will be zero (which will
  118. ;            cause the driver not to be installed at all).
  119. ;        DX    I/O port address of the clock; zero if no clock.
  120.  
  121. DriverInit proc    near
  122.  
  123.     ; BX will contain the port number from the argument (0 if none).
  124.     xor    bx, bx
  125.  
  126.     ; Skip over the driver file name
  127.     ; (look for space, slash, tab, or CR after name).
  128. skip_driver_name:
  129.     lodsb
  130.     cmp    al, CR
  131.     je    short port_done
  132.     cmp    al, ' '
  133.     je    short end_of_name
  134.     cmp    al, TAB
  135.     je    short end_of_name
  136.     cmp    al, '/'
  137.     jne    short skip_driver_name
  138. end_of_name:
  139.  
  140.     ; Process a port number argument, if any.
  141.     mov    cl, 4            ; for shifting
  142.     ;
  143. next_port_digit:
  144.     lodsb                ; get next (possible) digit
  145.     cmp    al, ' '
  146.     je    short next_port_digit    ; skip spaces
  147.     cmp    al, TAB
  148.     je    short next_port_digit    ; skip tabs
  149.     cmp    al, '/'
  150.     je    short next_port_digit    ; skip slashes
  151.     cmp    al, '0'
  152.     jb    short port_done
  153.     cmp    al, '9'
  154.     ja    short not_decimal
  155.     ;
  156. process_port_digit:
  157.     shl    bx, cl
  158.     and    al, 0Fh
  159.     add    bl, al            ; add new digit into total
  160.     jmp    short next_port_digit
  161.     ;
  162. not_decimal:
  163.     cmp    al, 'A'
  164.     jb    short port_done
  165.     cmp    al, 'F'
  166.     ja    short not_capital
  167.     ;
  168. alpha_digit:
  169.     add    al, 9            ; shift to range 10-15
  170.     jmp    short process_port_digit
  171.     ;
  172. not_capital:
  173.     cmp    al, 'a'
  174.     jb    short port_done
  175.     cmp    al, 'f'
  176.     ja    short port_done
  177.     jmp    short alpha_digit
  178.     ;
  179. port_done:
  180.     ; BX will now contain the port number argument, or zero if none.
  181.     and    bx, 0FFF0h        ; mask out low-order four bits
  182.  
  183.  
  184.     ; Make data addressable via DS (required for DOS calls and XLAT).
  185.     INIT_DS
  186.  
  187.     ; Print banner.
  188.     PRINT    Banner
  189.  
  190.     ; Look for the clock.
  191.     and    bx, bx
  192.     jz    short use_default_port    ; if BX=0, use default port list
  193.     mov    ThePort, bx        ; otherwise use only BX as port #
  194.     mov    bx, offset ThePort
  195.     jmp    short got_port
  196. use_default_port:
  197.     xor    bx, bx            ; use default port list
  198. got_port:
  199.     push    ds
  200.     call    LookForClock        ; returns in DX (I/O port)
  201.     pop    ds
  202.     and    dx, dx
  203.     jnz    short clock_found    ; DX=0 if no clock found
  204.  
  205.     ; Announce that no clock was found.
  206.     PRINT    NoClkFound
  207.     PRINT    Windup
  208.     xor    dx, dx            ; clock port = 0 (no clock)
  209.     xor    cx, cx            ; can toss the entire driver
  210.     ret
  211.  
  212. clock_found:
  213.     ; Format the clock's port address for output.
  214.     mov    bx, offset hex2asc    ; hex->ASCII conversion table
  215.     mov    cx, 4            ; for shifting
  216.     SPLIT    dh
  217.     xlat
  218.     SWAP
  219.     xlat
  220.     mov    word ptr [ClkAddr], ax
  221.     SPLIT    dl
  222.     xlat
  223.     SWAP
  224.     xlat
  225.     mov    word ptr [ClkAddr+2], ax
  226.     push    dx            ; save I/O port address
  227.  
  228.     ; Read the clock value.  This is done now for two reasons:
  229.     ; first, to set the BIOS time-of-day count; and second, to
  230.     ; announce the current date and time in the driver banner.
  231.     mov    ax, ds
  232.     mov    es, ax
  233.     mov    di, offset buffer
  234.     call    ClkToBuf
  235.  
  236.     ; Set the BIOS time-of-day count.
  237.     mov    cx, word ptr [buffer+2]
  238.     mov    dx, word ptr [buffer+4]
  239.     call    SetBIOS
  240.  
  241.     ; Format the current time in the driver banner.
  242.         mov    bx, offset bin2bcd    ; for XLAT
  243.     mov    cx, 4            ; for SPLIT
  244.     mov    dx, ('0' shl 8) + '0'    ; for ASCII conversion
  245.     ;
  246.     mov    al, byte ptr [buffer+3]    ; hours
  247.     xlat
  248.     SPLIT    al
  249.     add    ax, dx
  250.     SWAP
  251.     mov    word ptr [CurHour], ax
  252.     ;
  253.     mov    al, byte ptr [buffer+2]    ; minutes
  254.     xlat
  255.     SPLIT    al
  256.     add    ax, dx
  257.     SWAP
  258.     mov    word ptr [CurMin], ax
  259.     ;
  260.     mov    al, byte ptr [buffer+5]    ; seconds
  261.     xlat
  262.     SPLIT    al
  263.     add    ax, dx
  264.     SWAP
  265.     mov    word ptr [CurSec], ax
  266.     ;
  267.     mov    al, byte ptr [buffer+4]    ; 1/100 second
  268.     xlat
  269.     SPLIT    al
  270.     add    ax, dx
  271.     SWAP
  272.     mov    word ptr [CurHSec], ax
  273.  
  274.     ; Format the current date in the driver banner.  In order to
  275.     ; do this, it is necessary to convert the "long count" date
  276.     ; from the driver into a year, month, and day.
  277.     mov    ax, word ptr [buffer]    ; get long count
  278.     mov    bx, 1980        ; initial year
  279.     mov    cx, 365
  280.     ;
  281. try_next_year:
  282.     mov    dx, cx            ; 365 days in a year . . .
  283.     test    bl, 3
  284.     jnz    short not_leap_year    ; but in a leap year,
  285.     inc    dx            ;    it's 366 days instead
  286. not_leap_year:
  287.     sub    ax, dx            ; a full year of days left?
  288.     jb    found_year
  289.     inc    bx            ; if so, add one to year,
  290.     jmp    short try_next_year    ;    and try again
  291.     ;
  292. found_year:
  293.     add    ax, dx            ; if not, fix day count
  294.     cmp    ax, 59            ; if March or later,
  295.     jb    short leap_fix_done
  296.     test    bl, 3            ;    and not a leap year,
  297.     jz    short leap_fix_done
  298.     inc    ax            ;    add 1 to AX so we can pretend
  299.                     ;    later that February always has
  300.                     ;    29 days
  301. leap_fix_done:
  302.     push    ax            ; save day count for later
  303.     mov    ax, bx
  304.     mov    bl, 100
  305.     div    bl            ; split into century and year
  306.     mov    di, ax            ; save year part for later
  307.     ;
  308.         mov    bx, offset bin2bcd    ; for XLAT
  309.     mov    cx, 4            ; for SPLIT
  310.     mov    dx, ('0' shl 8) + '0'    ; for ASCII conversion
  311.     ;
  312.     xlat                ; century already in AL after DIV
  313.     SPLIT    al
  314.     add    ax, dx
  315.     SWAP
  316.     mov    word ptr [CurYear], ax
  317.     ;
  318.     mov    ax, di
  319.     SWAP
  320.     xlat                ; low-order two digits of year
  321.     SPLIT    al
  322.     add    ax, dx
  323.     SWAP
  324.     mov    word ptr [CurYear+2], ax
  325.     ;
  326.     pop    ax            ; back to month and day
  327.         mov    si, 0            ; initial month (January)
  328.     ;
  329. try_next_month:
  330.     sub    ax, word ptr [MonLen+si]
  331.     jb      short found_month
  332.     inc    si
  333.     inc    si
  334.     jmp    short try_next_month
  335.         ;
  336. found_month:
  337.     add    ax, word ptr [MonLen+si]
  338.     inc    ax            ; AL is now day number
  339.     ;
  340.         mov    bx, offset bin2bcd    ; for XLAT
  341.     mov    cx, 4            ; for SPLIT
  342.     mov    dx, ('0' shl 8) + '0'    ; for ASCII conversion
  343.     ;
  344.     xlat
  345.     SPLIT    al
  346.     add    ax, dx
  347.     SWAP
  348.     mov    word ptr [CurDay], ax
  349.     ;
  350.     shl    si, 1            ; SI = 4 * (month - 1)
  351.     mov    ax, word ptr [MonNam+si]
  352.     mov    word ptr [CurMon], ax
  353.     mov    ax, word ptr [MonNam+2+si]
  354.     mov    word ptr [CurMon+2], ax
  355.  
  356.     ; Announce that the clock was found, and the current time.
  357.     PRINT    ClkFound
  358.     PRINT    Windup
  359.     pop    dx            ; restore I/O port address
  360.  
  361.     ; Ready to return.
  362.     mov    cx, offset StartInit    ; can toss all the init code
  363.     ret
  364.  
  365. DriverInit endp
  366.  
  367. code    ends
  368.  
  369.     end
  370.