swatch.asm
comment *
MASM32 SDK
ml /c /AT /Fl swatch.asm
link16 /t swatch;
*
		.model	tiny
 
FP		struc
FP_OFF		dw	?
FP_SEG		dw	?
FP		ends
 
; Programmable Interrupt Controller / Master
MPIC_OCW1	equ	02h	; Operation Command Word
MPIC_OCW2	equ	00h
MPIC_IMR	equ	02h	; Interrupt Mask Reg.
 
; Programmable Interval Timer
PIT_CNT0	equ	71h	; Counter
PIT_MODE	equ	77h	; Mode Reg.
 
BIOS_FLAG	equ	0501h
 
CLOCK5		equ	24576	; 5MHz系
CLOCK8		equ	19968	; 8MHz系
 
LF		equ	0ah
CR		equ	0dh
ESCAPE		equ	1bh
 
MAX_SEC		equ	60
MAX_MSEC	equ	100
 
		.code
		.186
		org	0100h
 
;■
main		proc
		mov	ax, 2523h
		mov	dx, offset myint23
		int	21h
		mov	ah, 12h			; カーソル表示off
		int	18h
		call	disp
 
		call	settimer
@@loop:
		call	disp
		mov	ah, 0bh			; キーボードのステータスチェック
		int	21h
		cmp	al, 0
		je	@@loop
 
		mov	ah, 07h			; コンソールからの直接入力
		int	21h
		cmp	al, ESCAPE
		jne	@@loop
 
		call	resettimer
@@exit:
		mov	ah, 11h			; カーソル表示on
		int	18h
		mov	ah, 02h
		mov	dl, CR
		int	21h
		mov	dl, LF
		int	21h
		mov	ax, 4c00h
		int	21h
main		endp
 
;■
disp		proc
		cli
		mov	dl, [count_sec]
		mov	dh, [count_msec]
		sti
		mov	di, offset buffer
		cld
@@disp_sec:
		mov	al, dl
		aam
		or	ax, 3030h
		xchg	al, ah
		stosw
		inc	di
@@disp_msec:
		mov	al, dh
		aam
		or	ax, 3030h
		xchg	al, ah
		stosw
@@disp:
		mov	ah, 09h
		mov	dx, offset buffer
		int	21h
		ret
disp		endp
 
;■
myint23		proc	far
		call	resettimer
		mov	ah, 11h			; カーソル表示on
		int	18h
		stc
		ret				; retf
myint23		endp
 
;■
settimer	proc
		pushf
		push	es
@@setvector:
		mov	ax, 3508h
		int	21h
		mov	cs:[orgint08].FP.FP_SEG, es
		mov	cs:[orgint08].FP.FP_OFF, bx
 
		mov	ax, cs
		mov	ds, ax
		mov	dx, offset newint08
		mov	ax, 2508h
		int	21h
@@setpit:
		mov	bx, CLOCK5
		mov	ax, 0
		mov	es, ax
		test	byte ptr es:[BIOS_FLAG], 80h
		jz	@@skip
		mov	bx, CLOCK8
@@skip:
		cli
		mov	al, 00110110b
		out	PIT_MODE, al
		jmp	$+2
		jmp	$+2
		mov	al, bl
		out	PIT_CNT0, al
		jmp	$+2
		jmp	$+2
		mov	al, bh
		out	PIT_CNT0, al
@@setpic:
		in	al, MPIC_IMR
		and	al, 0feh		; タイマ割り込み許可
		out	MPIC_OCW1, al
 
		pop	es
		popf
		ret
settimer	endp
 
;■
resettimer	proc
		pushf
		cli
 
		in	al, MPIC_IMR
		or	al, 01h			; タイマ割り込み禁止
		out	MPIC_OCW1, al
@@resetvector:
		mov	ax, 2508h
		lds	dx, cs:[orgint08]
		int	21h
 
		popf
		ret
resettimer	endp
 
;■
newint08	proc	far
		push	ds
		push	es
		pusha
 
		mov	ax, cs
		mov	ds, ax
		mov	es, ax
		mov	si, offset count_msec
		mov	di, si
		std
@@count_msec:
		lodsb
		inc	al
		cmp	al, MAX_MSEC
		jne	@@return
		mov	al, 0
		stosb
@@count_sec:
		lodsb
		inc	al
		cmp	al, MAX_SEC
		jne	@@return
		mov	al, 0
@@return:
		stosb
 
		mov	al, 20h			; 割り込み処理終了(EOI)
		out	MPIC_OCW2, al
 
		popa
		pop	es
		pop	ds
		iret
newint08	endp
 
orgint08	dd	0
 
count_sec	db	0
count_msec	db	0
 
buffer		db	'00.00', CR, '$'
 
		end	main
 
最終更新:2018年08月21日 09:44