Tvůrce webu je i pro tebe! Postav třeba web. Bez grafika. Bez kodéra. Hned.
wz

DOS_CLK.ASM

Obsluha hodin


; ============================================================================
;
;                            LT-DOS - DOS clock
;
; ============================================================================

; ----------------------------------------------------------------------------
;                         Calculate day of week
; ----------------------------------------------------------------------------
; INPUT:	DS = data segment
; DESTROYS:	AX, CX, DX
; ----------------------------------------------------------------------------

CalcDayWeek:	mov	ax,[CurrDate]	; AX <- current date
		inc	ax
		inc	ax		; AX +2 (1/1/1980 is Tuesday, e.g. 2)
		xor	dx,dx		; DX <- 0
		mov	cx,7		; CX <- days in week
		div	cx		; calculate day of week
		mov	[CurrDayWeek],dl ; current day of week
		ret

; ----------------------------------------------------------------------------
;                          Get system date and time
; ----------------------------------------------------------------------------
; OUTPUT:	DS = data segment
; DESTROYS:	SI, ES
; ----------------------------------------------------------------------------

; ------------- Push registers

GetDateTime:	push	ax		; push AX
		push	bx		; push BX
		push	cx		; push CX
		push	dx		; push DX

; ------------- Prepare DDR table for read operation

		xor	ax,ax		; AL <- 0 unit, AH <- 0 media
		mov	bx,DOSClock	; BX <- DOS clock buffer
		mov	cx,CLOCKData_size ; size of data
		xor	dx,dx		; DX <- starting offset
		push	cs		; push CS
		pop	ds		; DS <- data segment
		call	InitR16DDR	; prepare DDR table

; ------------- Read system date and time

		push	cs		; push CS
		pop	es		; ES <- data segment
		lds	si,[ClockDev]	; DS:SI <- clock device header
		call	DevExec		; execute device service
		push	cs		; push CS
		pop	ds		; DS <- data segment

; ------------- Check if current date changed

		mov	ax,[DOSClockDate] ; AX <- date in days from 1/1/1980
		cmp	ax,[CurrDate]	; current date changed?
		je	GetDateTime9	; current date did not change

; ------------- Calculate new current date

		call	DOS2Date	; recalc DOS date do date
		mov	[CurrDayMonth],dx ; current day and month
		mov	al,100		; years in century
		mul	ch		; recalc century to years
		mov	ch,0		; CX = year in century
		add	ax,cx		; AX <- year
		mov	[CurrYear],ax	; current year

; ------------- Calculate day of week

		call	CalcDayWeek	; calculate day of week

; ------------- Pop registers

GetDateTime9:	pop	dx		; pop DX
		pop	cx		; pop CX
		pop	bx		; pop BX
		pop	ax		; pop AX
		ret

; ----------------------------------------------------------------------------
;                         Set system date or time
; ----------------------------------------------------------------------------
; INPUT:	AL = 0 for date
;			CX = year (1980-2099)
;			DH = month (1-12)
;			DL = day (1-31)
;		AL <> 0 for time
;	 		CH = hour (0 to 23)
;			CL = minute (0 to 59)
;			DH = second (0 to 59)
;			DL = 1/100 seconds (0 to 99)
; OUTPUT:	DS = data segment
; DESTROYS:	SI, ES
; NOTES:	Date and time must be valid!
; ----------------------------------------------------------------------------

; ------------- Push registers

SetDateTime:	push	ax		; push AX
		push	bx		; push BX
		push	cx		; push CX
		push	dx		; push DX

; ------------- Get system date and time (data segment -> DS)

		call	GetDateTime	; get system date and time

; ------------- Check if a date will be set

		or	al,al		; set date?
		jz	SetDateTime4	; set date

; ------------- Store current time

		mov	[DOSClockMinHour],cx ; store minute and hour
		mov	[DOSClockHundSec],dx ; store hundredth and second
		jmp	short SetDateTime6

; ------------- Store current date

SetDateTime4:	mov	[CurrDayMonth],dx ; store current day and month
		mov	[CurrYear],cx	; store current year

; ------------- Split year into year and century (-> CX)

		mov	al,100		; AL <- 100 years in century
		xchg	ax,cx		; AX <- year, CL <- 100
		div	cl		; split year
		xchg	al,ah		; AL <- year, AH <- century
		xchg	ax,cx		; CL <- year, CH <- century

; ------------- Recalc date to DOS date (-> AX)

		call	Date2DOS	; recalc date to DOS date
		mov	[CurrDate],ax	; store current date
		mov	[DOSClockDate],ax ; set new current date

; ------------- Calculate day of week

		call	CalcDayWeek	; calculate day of week

; ------------- Prepare DDR table for write operation

SetDateTime6:	xor	ax,ax		; AL <- 0 unit, AH <- 0 media
		mov	bx,DOSClock	; BX <- DOS clock buffer
		mov	cx,CLOCKData_size ; size of data
		xor	dx,dx		; DX <- starting offset
		call	InitW16DDR	; prepare DDR table

; ------------- Write system date and time

		push	cs		; push CS
		pop	es		; ES <- data segment
		lds	si,[ClockDev]	; DS:SI <- clock device header
		call	DevExec		; execute device service
		push	cs		; push CS
		pop	ds		; DS <- data segment

; ------------- Pop registers

		pop	dx		; pop DX
		pop	cx		; pop CX
		pop	bx		; pop BX
		pop	ax		; pop AX
		ret

; ----------------------------------------------------------------------------
;                   Int 21h, function 2Ah - Get system date
; ----------------------------------------------------------------------------
; INT21 INPUT:	AH = 2Ah (function code)
; INT21 OUTPUT:	AL = day of week (0-6, 0=Sunday, 1=Monday, ...)
;		CX = year (1980-2099)
;		DH = month (1-12)
;		DL = day (1-31)
; ----------------------------------------------------------------------------

; ------------- Get system date and time

Int212A:	call	GetDateTime	; get system date and time

; ------------- Return current date

		mov	cx,[CurrYear]	; CX <- year
		call	SetRegCX	; set year
		mov	dx,[CurrDayMonth] ; DL <- day, DH <- month
		call	SetRegDX	; set day and month
		mov	al,[CurrDayWeek] ; AL <- day of week
		ret

; ----------------------------------------------------------------------------
;                   Int 21h, function 2Bh - Set system date
; ----------------------------------------------------------------------------
; INT21 INPUT:	AH = 2Bh (function code)
;		CX = year (1980-2099)
;		DH = month (1-12)
;		DL = day (1-31)
; INT21 OUTPUT:	AL = result
;			0: successful
;			0ffh: invalid date, system date unchanged
; ----------------------------------------------------------------------------

; ------------- Check year

Int212B:	mov	al,0ffh		; AL <- 0ffh, invalid date flag
		cmp	cx,1980		; minimal year
		jb	Int212B8	; invalid year
		cmp	cx,2099		; maximal year
		ja	Int212B8	; invalid year

; ------------- Check month

		or	dh,dh		; minimal month
		jz	Int212B8	; invalid month
		cmp	dh,12		; maximal month
		ja	Int212B8	; invalid month

; ------------- Prepare days in February

		push	cx		; push CX
		sub	cx,1980		; CX <- offset from 1980
		call	PrepareFeb	; prepare February
		pop	cx		; pop CX

; ------------- Check day

		or	dl,dl		; minimal day
		jz	Int212B8	; invalid day
		push	bx		; push BX
		xor	bx,bx		; BX <- 0
		mov	bl,dh		; BL <- month
		cmp	dl,[cs:bx+DayMonthTab-1] ; check days in month
		pop	bx		; pop BX
		ja	Int212B8	; invalid day

; ------------- Set system date

		mov	al,0		; AL <- 0, flag to set date, result OK
		call	SetDateTime	; set system date
Int212B8:	ret

; ----------------------------------------------------------------------------
;                   Int 21h, function 2Ch - Get system time
; ----------------------------------------------------------------------------
; INT21 INPUT:	AH = 2Ch (function code)
; INT21 OUTPUT:	CH = hour (0 to 23)
;		CL = minute (0 to 59)
;		DH = second (0 to 59)
;		DL = 1/100 seconds (0 to 99)
; NOTES: Time resolution is 55 ms. On some systems DL may return 0.
; ----------------------------------------------------------------------------

; ------------- Get system date and time

Int212C:	call	GetDateTime	; get system date and time

; ------------- Return current time

		mov	cx,[DOSClockMinHour] ; CL <- minute, CH <- hour
		call	SetRegCX	; set minute and hour
		mov	dx,[DOSClockHundSec] ; DL <- hundredth, DH <- second
		call	SetRegDX	; set hundredth and second
		mov	al,0		; return code OK
		ret

; ----------------------------------------------------------------------------
;                   Int 21h, function 2Dh - Set system time
; ----------------------------------------------------------------------------
; INT21 INPUT:	AH = 2Dh (function code)
; 		CH = hour (0 to 23)
;		CL = minute (0 to 59)
;		DH = second (0 to 59)
;		DL = 1/100 seconds (0 to 99)
; INT21 OUTPUT:	AL = result
;			0: successful
;			0ffh: invalid time, system time unchanged
; ----------------------------------------------------------------------------

; ------------- Check time

Int212D:        mov	al,0ffh		; AL <- 0ffh, invalid time flag
		cmp	ch,23		; maximal hour
		ja	Int212D8	; invalid hour
		cmp	cl,59		; maximal minute
		ja	Int212D8	; invalid minute
		cmp	dh,59		; maximal second
		ja	Int212D8	; invalid second
		cmp	dl,99		; maximal hundredth
		ja	Int212D8	; invalid hundredth

; ------------- Set system time (here is AL = 0ffh)

		call	SetDateTime	; set system time
		mov	al,0		; return code OK
Int212D8:	ret

; ----------------------------------------------------------------------------
;                                    Data
; ----------------------------------------------------------------------------

; ------------- DOS clock data

DOSClock:				; structure CLOCKData
DOSClockDate:	dw	0		; date in days from 1/1/1980
DOSClockMinHour:
DOSClockMin:	db	0		; minute (0 to 59)
DOSClockHour:	db	0		; hour (0 to 23)
DOSClockHundSec:
DOSClockHund:	db	0		; hundredth second (0 to 99)
DOSClockSec:	db	0		; second (0 to 59)

CurrDate:	dw	0		; current date from 1/1/1980
CurrDayMonth:
CurrDay:	db	1		; currant day (1 to 31)
CurrMonth:	db	1		; current month (1 to 12)
CurrYear:	dw	1980		; current year (1980 to 2099)
CurrDayWeek:	db	2		; current day of week (0=Sunday to 6)

Zpět na stránku systému LT-DOS