     1                                  ;	TITLE MSCLOCK - DOS 3.3
     2                                  ;----------------------------------------------------------------
     3                                  ;								:
     4                                  ;		    CLOCK DEVICE DRIVER 			:
     5                                  ;								:
     6                                  ;								:
     7                                  ;   This file contains the Clock Device Driver. 		:
     8                                  ;								:
     9                                  ;   The routines in this files are:				:
    10                                  ;								:
    11                                  ;	routine 		function			:
    12                                  ;	------- 		--------			:
    13                                  ;	TIM$WRIT		Set the current time		:
    14                                  ;	TIM$READ		Read the current time		:
    15                                  ;	Time_To_Ticks		Convert time to corresponding	:
    16                                  ;				  number of clock ticks 	:
    17                                  ;								:
    18                                  ; The clock ticks at the rate of:				:
    19                                  ;								:
    20                                  ;	1193180/65536 ticks/second (about 18.2 ticks per second):
    21                                  ; See each routine for information on the use.			:
    22                                  ;								:
    23                                  ;----------------------------------------------------------------
    24                                  
    25                                  
    26                                  	itest equ 0
    27                                  	%include "entryseg.nas"
     1                              <1> 
     2                              <1> %ifndef ENTRYSEGNAS
     3                              <1> %define ENTRYSEGNAS 1
     4                              <1> 
     5                              <1> %include "lmacros3.mac"
     1                              <2> [list -]
     1          ******************  <2>  warning: redefining multi-line macro `struc' [-w+pp-macro-redef-multi]
    14                              <3> [list -]
    14                              <2> [list -]
     6                              <1> %include "entrysw.mac"
     1                              <2> 
     2                              <2> %ifndef __ENTRYSW_MAC__
     3                              <2>  %assign __ENTRYSW_MAC__ 1
     4                              <2> 
     5                              <2> %assign _DOSCODEHMA		1
     6                              <2> %assign _RELOCATEDOSCODE	1
     7                              <2> 
     8                              <2> 		; Write a label "%1" (only if DOSCODE isn't relocated) and
     9                              <2> 		; "relocated%1" (always).
    10                              <2> 	%imacro relocated 1-2.nolist
    11                              <2> %ifnidni %2, device
    12                              <2>  %ifnidni %2, amis
    13                              <2>   %ifn _RELOCATEDOSCODE
    14                              <2> %1:
    15                              <2> 	global %1
    16                              <2>   %endif
    17                              <2>  %endif
    18                              <2> %endif
    19                              <2> relocated%1:				; always used for local labels
    20                              <2> 	global relocated%1
    21                              <2> 	%endmacro
    22                              <2> 
    23                              <2> %if _RELOCATEDOSCODE
    24                              <2> DOSENTRYADJUSTSEGMENT equ 60h - 26h
    25                              <2> %else
    26                              <2> DOSENTRYADJUSTSEGMENT equ 0
    27                              <2> %endif
    28                              <2> DOSENTRYADJUSTOFFSET equ DOSENTRYADJUSTSEGMENT * 16
    29                              <2> 
    30                              <2> DOSENTRYDEVICEBASE equ 10h
    31                              <2> 
    32                              <2> %endif
     7                              <1> [list -]
    39                              <1> usesection DOSENTRY
    40                              <1> 
    41                              <1> %endif
    28                                  	%include "msgroup.mac"	;DEFINE CODE SEGMENT
     1                              <1> EVBOUND equ 1  ;THIS VALUE BEING 0 DOES NO BOUNDARY ALLIGNMENT, VALUE 1	  ;3.30
     2                              <1> 	     ; ALIGNS TO EVEN						  ;3.30
     3                              <1> 
     4                              <1> ; NASM original macros
     5                              <1> 
     6                              <1> %include "dcodeseg.nas"
     1                              <2> 
     2                              <2> %ifndef DCODESEGNAS
     3                              <2> %assign DCODESEGNAS 1
     4                              <2> 
     5                              <2> section DOSCODETABLE align=2 PUBLIC class=DOSCODE
     6                              <2> ; (no prior section) ; DOSCODETABLE		ENDS
     7                              <2> section DOSCODECODE align=1 PUBLIC class=DOSCODE
     8                              <2> ; (no prior section) ; DOSCODECODE		ENDS
     9                              <2> section DOSBIOCODE align=2 PUBLIC class=DOSCODE
    10                              <2> section BIOCODE	align=2 PUBLIC class=DOSCODE
    11                              <2> 
    12                              <2> %ifnidni DOSENTRYGROUP, DOSCODEGROUP
    13                              <2>  group DOSCODEGROUP DOSCODETABLE DOSCODECODE DOSBIOCODE BIOCODE
    14                              <2> %endif
    15                              <2> 
    16                              <2> %endif
     7                              <1> 
     8                              <1> 	%if EVBOUND	;;IF EVEN (WORD) ALLIGNMENT IS REQUESTED,	  ;3.30
     9                              <1> 
    10                              <1> %imacro EVENB 0.nolist
    11                              <1> 	EVEN	;;ADJUST TO EVEN BOUNDARY
    12                              <1> %endmacro
    13                              <1> 
    14                              <1> %imacro ODD 0.nolist
    15                              <1> %if (($ - $$) % 2) == 0
    16                              <1> 	db ?
    17                              <1> %endif
    18                              <1> %endmacro
    19                              <1> 
    20                              <1> 	%else	;;SINCE EVEN ALLIGNMENT IS NOT DESIRED, JUST USE BYTE ALLI;3.30 GNMENT
    21                              <1> 
    22                              <1> %imacro EVENB 0.nolist
    23                              <1> ;;REQUEST FOR WORD ALLIGNMENT DOES NOTHING				  ;3.30
    24                              <1> %endmacro
    25                              <1> 
    26                              <1> %imacro ODD 0.nolist
    27                              <1> ;;REQUEST FOR ODD ALLIGNMENT DOES NOTHING				  ;3.30
    28                              <1> %endmacro
    29                              <1> 
    30                              <1> 	%endif								  ;3.30
    31                              <1> 
    32                              <1> %imacro CODE_SEGMENT 0.nolist
    33                              <1> 	section BIOCODE
    34                              <1> %endmacro
    35                              <1> 
    36                              <1> ; end of NASM original macros
    37                              <1> 
    38                              <1> 	CODE_SEGMENT							  ;3.30
    39                              <1> 	ASSUME	CS:BIOCODE 						  ;3.30
    40                              <1> 									  ;3.30
    29                                  	%include "msmacro.mac"
     1                              <1> 
     2                              <1> %include "dcodeseg.nas"
     1                              <2> 
     2                              <2> %ifndef DCODESEGNAS
     3                              <2> %assign DCODESEGNAS 1
     4                              <2> 
     5                              <2> section DOSCODETABLE align=2 PUBLIC class=DOSCODE
     6                              <2> ; (no prior section) ; DOSCODETABLE		ENDS
     7                              <2> section DOSCODECODE align=1 PUBLIC class=DOSCODE
     8                              <2> ; (no prior section) ; DOSCODECODE		ENDS
     9                              <2> section DOSBIOCODE align=2 PUBLIC class=DOSCODE
    10                              <2> section BIOCODE	align=2 PUBLIC class=DOSCODE
    11                              <2> 
    12                              <2> %ifnidni DOSENTRYGROUP, DOSCODEGROUP
    13                              <2>  group DOSCODEGROUP DOSCODETABLE DOSCODECODE DOSBIOCODE BIOCODE
    14                              <2> %endif
    15                              <2> 
    16                              <2> %endif
     3                              <1> section BIOCODE
     4                              <1> 
     5                              <1> ;
     6                              <1> ; This file contains three macros used in debugging the system.  If the
     7                              <1> ; variable "itest" (in msbio.asm) is nonzero code is included in the
     8                              <1> ; modules to print debugging messages.	The level of debugging is controlled
     9                              <1> ; by the value of the variable fTestBits in msbio.asm.	Specific bits in
    10                              <1> ; the variable determine which messages to print.  The equ's below tell
    11                              <1> ; which bits control which funcitons.  For example the fifth bit
    12                              <1> ; cooresponds to disk activity (see fTestDisk equ below).
    13                              <1> ;
    14                              <1> ;   The macros in the file are:
    15                              <1> ;
    16                              <1> ;	message    Prints an ascii string on the screen.
    17                              <1> ;		   Example usage:
    18                              <1> ;
    19                              <1> ;		      message fTestDisk, <"Start Disk Write", CR, LF>
    20                              <1> ;		      message fTestINIT, <"Begin BDS initialization">
    21                              <1> ;
    22                              <1> ;
    23                              <1> ;	MNUM	   Print the value in a register or memory location on
    24                              <1> ;		   the screen. Value is displayed in hex.
    25                              <1> ;		   Usage:
    26                              <1> ;		      MNUM  bitpattern, valueLocation
    27                              <1> ;
    28                              <1> ;		   valueLocation is typically a regester:
    29                              <1> ;
    30                              <1> ;		      mnum  fTestCom, AX
    31                              <1> ;		      mnum  fTestDisk, DX
    32                              <1> ;
    33                              <1> ;		   ValueLocation can also be a memory location:
    34                              <1> ;
    35                              <1> ;		      mnum  fTestINIT, Final_Dos_Location
    36                              <1> ;
    37                              <1> ;		   If no valueLocation is given the macro defaults to
    38                              <1> ;		   the BX register.
    39                              <1> ;
    40                              <1> ;	ZWAIT	    Stops the program until any key is pressed.
    41                              <1> ;
    42                              <1> ;
    43                              <1> ;	The three macros preserve all register values.	If "test" is zero
    44                              <1> ;	defined during assembly then the  marco produce no code.
    45                              <1> ;
    46                              <1> 
    47                              <1> 	%IF	itest							  ;3.30
    48                              <1> 		EXTRN	MSGOUT:NEAR,MSGNUM:NEAR 			  ;3.30
    49                              <1> 	    EXTRN   NUMBUF:BYTE,DIGITS:BYTE,FTESTBITS:WORD		  ;3.30
    50                              <1> 		EXTRN	DUMPBYTES:NEAR,OUTCHAR:NEAR,HEX_TO_ASCII:NEAR	  ;3.30
    51                              <1> 
    52                              <1> 
    53                              <1> fTestALL    equ     1111111111111111b	; watch everything
    54                              <1> fTestHARD   equ     0000000000000001b	; watch hard disk initialization
    55                              <1> fTest96     equ     0000000000000010b	; watch 96 tpi activity
    56                              <1> FTEST13     EQU     0000000000000100B	; WATCH INT 13 ACTIVITY 	  ;3.30
    57                              <1> FTESTCOM    EQU     0000000000001000B	; WATCH PACKET ACTIVITY 	  ;3.30
    58                              <1> FTESTINIT   EQU     0000000000010000B	; WATCH INITIALIZATION MESSAGES   ;3.30
    59                              <1> FTESTDISK   EQU     0000000000100000B	; WATCH DISK DEVICE DRIVER CALLS  ;3.30
    60                              <1> FTESTCON    EQU     0000000001000000B	; WATCH SYSTEM WAIT ACTIVITY IN CO;3.30 NSOLE
    61                              <1> FtestClock  equ     0000000010000000b	; wathc clock device  5/2/86  ;3.30
    62                              <1> 
    63                              <1> ; NASM original macros
    64                              <1> 
    65                              <1> ;
    66                              <1> ; message macro -- see above for description
    67                              <1> ;
    68                              <1> 
    69                              <1> %unimacro stripangles 2+.nolist
    70                              <1> 
    71                              <1> %imacro stripangles 2+.nolist
    72                              <1> %defstr %%param %2
    73                              <1> %rep 16
    74                              <1>  %substr %%opening %%param 1
    75                              <1>  %ifidn %%opening, '<'
    76                              <1>   %substr %%param %%param 2,-1
    77                              <1>  %endif
    78                              <1> %endrep
    79                              <1> %rep 16
    80                              <1>  %strlen %%length %%param
    81                              <1>  %substr %%closing %%param %%length
    82                              <1>  %ifidn %%closing, '>'
    83                              <1>   %substr %%param %%param 1,-2
    84                              <1>  %endif
    85                              <1> %endrep
    86                              <1> %deftok %%token %%param
    87                              <1> %1 %%token
    88                              <1> %endmacro
    89                              <1> 
    90                              <1> %imacro MESSAGE 2+
    91                              <1> 	jmp short %%b
    92                              <1> %%a:
    93                              <1> 	stripangles db, %2
    94                              <1> 	db 0
    95                              <1> %%b:	push	SI
    96                              <1> 	push	AX
    97                              <1> 	mov	AX, %1
    98                              <1> 	mov	SI, OFFSET %%a
    99                              <1> 	call	MSGOUT
   100                              <1> 	pop	AX
   101                              <1> 	pop	SI
   102                              <1> %endmacro
   103                              <1> 
   104                              <1> 
   105                              <1> ;
   106                              <1> ; mnum macro -- see above for description
   107                              <1> ;
   108                              <1> 
   109                              <1> %imacro MNum 1-2
   110                              <1> 	push	AX
   111                              <1> %ifempty %2
   112                              <1> 	mov	AX,%1
   113                              <1> 	call	MSGNUM
   114                              <1> %else
   115                              <1> 	push	BX
   116                              <1> 	mov	BX,%2
   117                              <1> 	mov	AX,%1
   118                              <1> 	call	MSGNUM
   119                              <1> 	pop	BX
   120                              <1> %endif
   121                              <1> 	pop	AX
   122                              <1> %endmacro
   123                              <1> 
   124                              <1> 
   125                              <1> ;
   126                              <1> ; zwait macro -- see above for description
   127                              <1> ;
   128                              <1> 
   129                              <1> %imacro ZWAIT 0
   130                              <1> 	Message fTestALL,<"? ">
   131                              <1> 	CALL	ZWAITrtn
   132                              <1> %endmacro
   133                              <1> 
   134                              <1> ZWAITrtn:
   135                              <1> 	pushf				; save the flags
   136                              <1> 	push	AX			; preserve AX
   137                              <1> 	xor	AH, AH			; set command to get character ;3.30*
   138                              <1> 	int	16h			; call rom keyboard routine    ;3.30*
   139                              <1> 	pop	AX			; restore AX
   140                              <1> 	popf				; restore the flags
   141                              <1> 	ret
   142                              <1> 
   143                              <1> ;Dump_byte dumps the memory contents in hex. 				  ;3.30
   144                              <1> ;DUMPOFFLABEL should be a label or a variable defined in DUMPSEG.	  ;3.30
   145                              <1> %imacro DUMP_BYTE 3
   146                              <1> 	push	es							  ;3.30
   147                              <1> 	PUSH	DS							  ;3.30
   148                              <1> 	PUSH	SI							  ;3.30
   149                              <1> 	PUSH	CX							  ;3.30
   150                              <1> 									  ;3.30
   151                              <1> 	MOV	CX, %1							  ;3.30
   152                              <1> 	MOV	DS, CX							  ;3.30
   153                              <1> 	MOV	SI, OFFSET %2						  ;3.30
   154                              <1> 	MOV	CX, %3							  ;3.30
   155                              <1> 	call	dumpbytes						  ;3.30
   156                              <1> 									  ;3.30
   157                              <1> 	POP	CX							  ;3.30
   158                              <1> 	POP	SI							  ;3.30
   159                              <1> 	POP	DS							  ;3.30
   160                              <1> 	pop	es							  ;3.30
   161                              <1> %endmacro								  ;3.30
   162                              <1> 									  ;3.30
   163                              <1> ;Dump_Byte_Reg dumps the memory contents in hex. -  4/9/86		  ;3.30
   164                              <1> ;DUMPOFFREG should be a register contains the offset value in DUMPSEG.	  ;3.30
   165                              <1> %imacro DUMP_BYTE_REG 3
   166                              <1> DUMP_BYTE_REG	MACRO	DUMPSEG, DUMPOFFREG, BYTELENGTH 		  ;3.30
   167                              <1> 	push	es							  ;3.30
   168                              <1> 	PUSH	DS							  ;3.30
   169                              <1> 	PUSH	SI							  ;3.30
   170                              <1> 	PUSH	CX							  ;3.30
   171                              <1> 									  ;3.30
   172                              <1> 	MOV	CX, %1							  ;3.30
   173                              <1> 	MOV	DS, CX							  ;3.30
   174                              <1> 	MOV	SI, %2							  ;3.30
   175                              <1> 	MOV	CX, %3							  ;3.30
   176                              <1> 	call	dumpbytes						  ;3.30
   177                              <1> 									  ;3.30
   178                              <1> 	POP	CX							  ;3.30
   179                              <1> 	POP	SI							  ;3.30
   180                              <1> 	POP	DS							  ;3.30
   181                              <1> 	pop	es							  ;3.30
   182                              <1> %endmacro								  ;3.30
   183                              <1> 
   184                              <1> %else
   185                              <1> 		; if test is not defined then make macro into null statements
   186                              <1> %imacro Message 0-1+.nolist
   187                              <1> %endmacro
   188                              <1> 
   189                              <1> %imacro MNUM 0-1+.nolist
   190                              <1> %endmacro
   191                              <1> 
   192                              <1> %imacro ZWAIT 0-1+.nolist
   193                              <1> %endmacro
   194                              <1> 
   195                              <1> %imacro DUMP_BYTE 0-1+.nolist
   196                              <1> %endmacro
   197                              <1> 
   198                              <1> %imacro DUMP_BYTE_REG 0-1+.nolist
   199                              <1> %endmacro
   200                              <1> 
   201                              <1> %endif
   202                              <1> 
   203                              <1> %unimacro PATHSTART 2
   204                              <1> %unimacro PATHEND 2
   205                              <1> 
   206                              <1> %imacro PATHSTART 2
   207                              <1> 	%IF	PATHGEN							  ;3.30
   208                              <1> 	    PUBLIC  %2%1S,%2%1E						  ;3.30
   209                              <1> 	    %2%1S LABEL	 BYTE						  ;3.30
   210                              <1> 	%ENDIF								  ;3.30
   211                              <1> %endmacro								  ;3.30
   212                              <1> 									  ;3.30
   213                              <1> %imacro PATHEND 2
   214                              <1> 	%IF	PATHGEN							  ;3.30
   215                              <1> 	    %2%1E LABEL	 BYTE						  ;3.30
   216                              <1> 	%ENDIF								  ;3.30
   217                              <1> %endmacro								  ;3.30
    30                                  	%include "ddataseg.nas"
     1                              <1> 
     2                              <1> %include "lmacros3.mac"
     1                              <2> [list -]
     3                              <1> 
     4                              <1> addsection DOSSTART, align=16 PUBLIC class=DOSSTART
     5                              <1> ; (no prior section) ; DOSSTART		ENDS
     6                              <1> 
     7                              <1> addsection DOSSTARTJUMP, align=1 PUBLIC class=START
     8                              <1> ; (no prior section) ; DOSSTARTJUMP		ENDS
     9                              <1> 
    10                              <1> addsection CONSTANTS, align=2 PUBLIC class=CONST
    11                              <1> ; (no prior section) ; CONSTANTS	ENDS
    12                              <1> 
    13                              <1> addsection DATA, align=2 PUBLIC class=DATA
    14                              <1> ; (no prior section) ; DATA		ENDS
    15                              <1> 
    16                              <1> addsection TABLE, align=2 PUBLIC class=TABLE
    17                              <1> ; (no prior section) ; TABLE		ENDS
    18                              <1> 
    19                              <1> addsection DOSDATATABLE, align=2 PUBLIC class=DOSDATACODE
    20                              <1> ; (no prior section) ; DOSDATATABLE		ENDS
    21                              <1> 
    22                              <1> addsection DOSDATACODE, align=1 PUBLIC class=DOSDATACODE
    23                              <1> ; (no prior section) ; DOSDATACODE		ENDS
    24                              <1> 
    25                              <1> addsection DOSBIODATA, align=2 PUBLIC class=DOSBIODATA
    26                              <1> 
    27                              <1> addsection LAST, align=16 PUBLIC class=LAST
    28                              <1> ; (no prior section) ; LAST		ENDS
    29                              <1> 
    30                              <1> group DOSGROUP DOSSTART DOSSTARTJUMP CONSTANTS DATA TABLE DOSDATATABLE DOSDATACODE DOSBIODATA LAST
    31                                  
    32                                  usesection DOSBIODATA
    33                                  
    34                                  	EXTRN EXIT:NEAR
    35                                  ;
    36                                  ; DAYCNT is the number of days since 1-1-80.
    37                                  ; Each time the clock is read it is necessary to check if another day has
    38                                  ; passed.  The ROM only returns the day rollover once so if it is missed
    39                                  ; the time will be off by a day.
    40                                  ;
    41                                  	EXTRN DAYCNT:WORD	;MSDATA
    42                                  
    43                                  	extern	HaveCMOSClock
    44                                  	extern	base_century
    45                                  	extern	base_year
    46                                  	extern	month_tab
    47                                  
    48                                  
    49                                  addsection BIOCODE
    50                                  
    51                                  	extern	near_bin_to_bcd
    52                                  	extern	near_daycnt_to_day
    53                                  	extern	near_time_to_ticks
    54                                  
    55                                  ;--------------------------------------------------------------------
    56                                  ;
    57                                  ; Settime sets the current time
    58                                  ;
    59                                  ; On entry [ES:DI] has the current time:
    60                                  ;
    61                                  ;	number of days since 1-1-80	(WORD)
    62                                  ;	minutes (0-59)			(BYTE)
    63                                  ;	hours (0-23)			(BYTE)
    64                                  ;	hundredths of seconds (0-99)	(BYTE)
    65                                  ;	seconds (0-59)			(BYTE)
    66                                  ;
    67                                  ; Each number has been checked for the correct range.
    68                                  ;
    69                                  	PUBLIC TIM$WRIT
    70                                  TIM$WRIT PROC	NEAR
    71                                   assume ds:DOSGROUP, es:nothing, ss:nothing
    72 00000000 268B05                  	mov	AX,WORD PTR [ES:DI]
    73 00000003 50                      	push	AX		;DAYCNT. We need to set this at the very
    74                                  				;  end to avoid tick windows.
    75                                  ;;Rev 3.30 Modification
    76 00000004 803E[0000]00            	cmp	byte [HaveCMOSClock], 0
    77 00000009 7423                    	je	No_CMOS_1
    78 0000000B 268A4503                	mov	al,[es:di+3]		;get binary hours
    79 0000000F E8(0000)                	call	near_bin_to_bcd		;convert to BCD
    80 00000012 88C5                    	mov	ch,al			;CH = BCD hours
    81 00000014 268A4502                	mov	al,[es:di+2]		;get binary minutes
    82 00000018 E8(0000)                	call	near_bin_to_bcd		;convert to BCD
    83 0000001B 88C1                    	mov	cl,al			;CL = BCD minutes
    84 0000001D 268A4505                	mov	al,[es:di+5]		;get binary seconds
    85 00000021 E8(0000)                	call	near_bin_to_bcd		;convert to BCD
    86 00000024 88C6                    	mov	dh,al			;DH = BCD seconds
    87 00000026 B200                    	mov	dl,0			;DL = 0 (ST) or 1 (DST)
    88 00000028 FA                      	cli				;turn off timer
    89 00000029 B403                    	mov	ah,03h			;set RTC time
    90 0000002B CD1A                    	int	1Ah			;call rom bios clock routine
    91 0000002D FB                      	sti
    92                                  
    93                                  ;;End of Modification
    94                                  No_CMOS_1:
    95 0000002E 268B4D02                	mov	CX,WORD PTR [ES:DI+2]
    96 00000032 268B5504                	mov	DX,WORD PTR [ES:DI+4]
    97                                  ;;Rev 3.30 Modification
    98 00000036 E81D00                  	call	near_time_to_ticks	; convert time to ticks
    99                                  				;CX:DX now has time in ticks
   100 00000039 FA                      	cli			; Turn off timer
   101 0000003A B401                    	mov	AH, 1		; command is set time in clock
   102 0000003C CD1A                    	int	1Ah		; call rom-bios clock routines
   103 0000003E 8F06[0000]              	pop	word [DAYCNT]
   104 00000042 FB                      	sti
   105                                  ;CMOS clock -------------------------------------
   106 00000043 803E[0000]00            	cmp	byte [HaveCMOSClock], 0
   107 00000048 7409                    	je	No_CMOS_2
   108 0000004A E8(0000)                	call	near_daycnt_to_day
   109 0000004D FA                      	cli			; Turn off timer
   110 0000004E B405                    	mov	AH,05h		; set RTC date
   111 00000050 CD1A                    	int	1Ah		; call rom-bios clock routines
   112 00000052 FB                      	sti
   113                                  ;------------------------------------------------
   114                                  
   115                                  No_CMOS_2:
   116 00000053 E9(0000)                	jmp	EXIT
   117                                  TIM$WRIT ENDP
   118                                  ;;End of Modification
   119                                  
   120                                  
   121                                  ;
   122                                  ; convert time to ticks
   123                                  ; input : time in CX and DX
   124                                  ; ticks returned in CX:DX
   125                                  ;
   126                                  near_time_to_ticks PROC near
   127                                  
   128                                  		; first convert from Hour,min,sec,hund. to
   129                                  		; total number of 100th of seconds
   130 00000056 B03C                    	mov	AL,60
   131 00000058 F6E5                    	mul	CH		;Hours to minutes
   132 0000005A B500                    	mov	CH,0
   133 0000005C 01C8                    	add	AX,CX		;Total minutes
   134 0000005E B97017                  	mov	CX,6000 	;60*100
   135 00000061 89D3                    	mov	BX,DX		;Get out of the way of the multiply
   136 00000063 F7E1                    	mul	CX		;Convert to 1/100 sec
   137 00000065 89C1                    	mov	CX,AX
   138 00000067 B064                    	mov	AL,100
   139 00000069 F6E7                    	mul	BH		;Convert seconds to 1/100 sec
   140 0000006B 01C1                    	add	CX,AX		;Combine seconds with hours and min.
   141 0000006D 83D200                  	adc	DX,0		;Ripple carry
   142 00000070 B700                    	mov	BH,0
   143 00000072 01D9                    	add	CX,BX		;Combine 1/100 sec
   144 00000074 83D200                  	adc	DX,0
   145                                  
   146                                  ;;Rev 3.30 Modification
   147                                  ;DX:CX IS TIME IN 1/100 SEC
   148 00000077 92                      	XCHG	AX,DX
   149 00000078 91                      	XCHG	AX,CX		;NOW TIME IS IN CX:AX
   150 00000079 BB0BE9                  	MOV	BX,59659
   151 0000007C F7E3                    	MUL	BX		;MULTIPLY LOW HALF
   152 0000007E 87D1                    	XCHG	DX,CX
   153 00000080 92                      	XCHG	AX,DX		;CX->AX, AX->DX, DX->CX
   154 00000081 F7E3                    	MUL	BX		;MULTIPLY HIGH HALF
   155 00000083 01C8                    	ADD	AX,CX		;COMBINE OVERLAPPING PRODUCTS
   156 00000085 83D200                  	ADC	DX,0
   157 00000088 92                      	XCHG	AX,DX		;AX:DX=TIME*59659
   158 00000089 BB0500                  	MOV	BX,5
   159 0000008C F6F3                    	DIV	BL		;DIVIDE HIGH HALF BY 5
   160 0000008E 88C1                    	MOV	CL,AL
   161 00000090 B500                    	MOV	CH,0
   162 00000092 88E0                    	MOV	AL,AH		;REMAINDER OF DIVIDE-BY-5
   163 00000094 98                      	CBW
   164 00000095 92                      	XCHG	AX,DX		;USE IT TO EXTEND LOW HALF
   165 00000096 F7F3                    	DIV	BX		;DIVDE LOW HALF BY 5
   166 00000098 89C2                    	MOV	DX,AX
   167                                  			; CX:DX is now number of ticks in time
   168 0000009A C3                      	ret
   169                                  near_time_to_ticks ENDP
   170                                  ;;End of Modification
   171                                  
   172                                  
   173                                  ;
   174                                  ; Gettime reads date and time
   175                                  ; and returns the following information:
   176                                  ;
   177                                  ;	[ES:DI]  =count of days since 1-1-80
   178                                  ;	[ES:DI+2]=hours
   179                                  ;	[ES:DI+3]=minutes
   180                                  ;	[ES:DI+4]=seconds
   181                                  ;	[ES:DI+5]=hundredths of seconds
   182                                  ;
   183                                  	PUBLIC TIM$READ
   184                                  TIM$READ PROC	NEAR
   185                                   assume ds:DOSGROUP, es:nothing, ss:nothing
   186                                  				; read the clock
   187 0000009B 30E4                    	xor	AH, AH		; set command to read clock
   188 0000009D CD1A                    	int	1Ah		; call rom-bios to get time
   189                                  
   190 0000009F 08C0                    	or	al,al		; check for a new day
   191 000000A1 7404                    	jz	noroll1 	; if al=0 then don't reset day count
   192 000000A3 FF06[0000]              	INC	word [DAYCNT]	; CATCH ROLLOVE
   193                                  noroll1:
   194 000000A7 8B36[0000]              	MOV	SI,[DAYCNT]
   195                                  
   196                                  ;
   197                                  ; we now need to convert the time in tick to the time in 100th of
   198                                  ; seconds.  The relation between tick and seconds is:
   199                                  ;
   200                                  ;		 65536 seconds
   201                                  ;	       ----------------
   202                                  ;		1,193,180 tick
   203                                  ;
   204                                  ; To get to 100th of second we need to multiply by 100. The equation is:
   205                                  ;
   206                                  ;	Ticks from clock  * 65536 * 100
   207                                  ;      ---------------------------------  = time in 100th of seconds
   208                                  ;		1,193,180
   209                                  ;
   210                                  ; Fortunately this fromula simplifies to:
   211                                  ;
   212                                  ;	Ticks from clock * 5 * 65,536
   213                                  ;      --------------------------------- = time in 100th of seconds
   214                                  ;		59,659
   215                                  ;
   216                                  ; The calculation is done by first multipling tick by 5. Next we divide by
   217                                  ; 59,659.  In this division we multiply by 65,536 by shifting the dividend
   218                                  ; my 16 bits to the left.
   219                                  ;
   220                                  ; start with ticks in CX:DX
   221                                  ; multiply by 5
   222 000000AB 89C8                    	MOV	AX,CX
   223 000000AD 89D3                    	MOV	BX,DX
   224 000000AF D1E2                    	SHL	DX,1
   225 000000B1 D1D1                    	RCL	CX,1		;TIMES 2
   226 000000B3 D1E2                    	SHL	DX,1
   227 000000B5 D1D1                    	RCL	CX,1		;TIMES 4
   228 000000B7 01DA                    	ADD	DX,BX
   229 000000B9 11C8                    	ADC	AX,CX		;TIMES 5
   230 000000BB 92                      	XCHG	AX,DX		
   231                                  	
   232                                  
   233                                  ; now have ticks * 5 in DX:AX
   234                                  ; we now need to multiply by 65,536 and divide by 59659 d.
   235                                  
   236 000000BC B90BE9                  	mov	CX,59659	; get divisor
   237 000000BF F7F1                    	div	CX
   238                                  				; DX now has remainder
   239                                  				; AX has high word of final quotient
   240 000000C1 89C3                    	mov	BX,AX		; put high work if safe place
   241 000000C3 31C0                    	xor	AX,AX		; this is the multiply by 65536
   242 000000C5 F7F1                    	div	CX		; BX:AX now has time in 100th of seconds
   243                                  
   244                                  ;
   245                                  ;Rounding based on the remainder may be added here
   246                                  ;The result in BX:AX is time in 1/100 second.
   247 000000C7 89DA                    	mov	DX,BX
   248 000000C9 B9C800                  	mov	CX,200		;Extract 1/100's
   249                                  ;Division by 200 is necessary to ensure no overflow--max result
   250                                  ;is number of seconds in a day/2 = 43200.
   251 000000CC F7F1                    	div	CX
   252 000000CE 80FA64                  	cmp	DL,100		;Remainder over 100?
   253 000000D1 7203                    	jb	NOADJ
   254 000000D3 80EA64                  	sub	DL,100		;Keep 1/100's less than 100
   255                                  NOADJ:
   256 000000D6 F5                      	cmc			;If we subtracted 100, carry is now set
   257 000000D7 88D3                    	mov	BL,DL		;Save 1/100's
   258                                  ;To compensate for dividing by 200 instead of 100, we now multiply
   259                                  ;by two, shifting a one in if the remainder had exceeded 100.
   260 000000D9 D1D0                    	rcl	AX,1
   261 000000DB B200                    	mov	DL,0
   262 000000DD D1D2                    	rcl	DX,1
   263 000000DF B93C00                  	mov	CX,60		;Divide out seconds
   264 000000E2 F7F1                    	div	CX
   265 000000E4 88D7                    	mov	BH,DL		;Save the seconds
   266 000000E6 F6F1                    	div	CL		;Break into hours and minutes
   267 000000E8 86C4                    	xchg	AL,AH
   268                                  
   269                                  ;Time is now in AX:BX (hours, minutes, seconds, 1/100 sec)
   270                                  
   271 000000EA 50                      	push	AX
   272 000000EB 89F0                    	MOV	AX,SI		; DAYCNT
   273 000000ED AB                      	stosw
   274 000000EE 58                      	pop	AX
   275 000000EF AB                      	stosw
   276 000000F0 89D8                    	mov	AX,BX
   277 000000F2 AB                      	stosw
   278 000000F3 E9(0000)                	jmp	EXIT
   279                                  
   280                                  TIM$READ ENDP
   281                                  ; (no prior section) ; CODE	ENDS
   282                                  	END
   283                                  
   284                                  
