misc/rtctrnstest.s
;========================================================================================
;  rtctrnstest.s
;  Copyright (C) 2003-2026 Makoto Kamada
;
;  This file is part of the XEiJ (X68000 Emulator in Java).
;  You can use, modify and redistribute the XEiJ if the conditions are met.
;  Read the XEiJ License for more details.
;  https://stdkmd.net/xeij/
;========================================================================================

;----------------------------------------------------------------
;	名前
;		rtctrnstest.x
;	機能
;		RTCのカウンタが実機と同じように遷移しているか確認します
;	環境
;		X680x0シリーズ全機種およびエミュレータ
;	注意
;		時計が狂います。終了後に時計を合わせてください
;	操作
;		A>rtctrnstest.x
;		RTCのカウンタが実機と同じように遷移しているか確認します
;		....................................................................................
;		8495 成功, 0 失敗
;		時計を合わせてください
;		A>
;----------------------------------------------------------------

	.include	control2.mac
	.include	doscall.mac
	.include	misc.mac
	.include	ppi.equ
	.include	push2.mac
	.include	rtc.equ

;レジスタ
dWH	reg	d1	;書き込む値
dWL	reg	d2
dPH	reg	d3	;前回読み出した値
dPL	reg	d4
dRH	reg	d5	;読み出した値
dRL	reg	d6
dT	reg	d7	;テンポラリ
aTRY	reg	a2	;試行回数
aOH	reg	a3	;前々回読み出した値
aOL	reg	a4

;ウェイト
aPPIA	reg	a5
	lea.l	PPI_PORT_A,aPPIA
wait	.macro
		tst.b	(aPPIA)
		tst.b	(aPPIA)
	.endm

;RTCアクセス
aRTC	reg	a6
	lea.l	RTC_0_ONE_SECOND,aRTC
rtc	reg	-RTC_0_ONE_SECOND(aRTC)
read_rtc	.macro	src,dst
		moveq.l	#$0F,dst
		and.b	(src)rtc,dst
		wait
	.endm
write_rtc	.macro	src,dst
		move.b	src,(dst)rtc
		wait
	.endm

;モード
mode_clear	.macro	mask
		read_rtc	RTC_MODE,dT
		and.b	#.notb.(mask),dT
		write_rtc	dT,RTC_MODE
	.endm
mode_set	.macro	mask
		read_rtc	RTC_MODE,dT
		or.b	#(mask),dT
		write_rtc	dT,RTC_MODE
	.endm
clock_stop	.macro
		mode_clear	RTC_MODE_CLOCK_MASK
	.endm
clock_start	.macro
		mode_set	RTC_MODE_CLOCK_MASK
	.endm
bank_0	.macro
		mode_clear	RTC_MODE_BANK_MASK
	.endm
bank_1	.macro
		mode_set	RTC_MODE_BANK_MASK
	.endm

;リセット
clock_reset	.macro
		write_rtc	#RTC_RESET_16HZ_MASK|RTC_RESET_CLOCK_MASK,RTC_RESET
		write_rtc	#RTC_RESET_16HZ_MASK,RTC_RESET
	.endm

;タイトル
	lea.l	title_message,a0
	jbsr	print

;データ
	move.l	#data_table,data_pointer
	clr.l	passed_counter
	clr.l	failed_counter

;スーパーバイザモード
	supervisormode

;カウンタ停止
	clock_stop

;カウンタ保存
	bsr	read_counters
	move.l	dRH,saved_counters
	move.l	dRL,saved_counters+4

;書き込む値のループ
	move.w	#100,dot_counter
	dostart
		move.l	(a0)+,dWL
		move.l	a0,data_pointer
	;3回続けて失敗したら遷移が間違っていると判断する
		movea.w	#3-1,aTRY
		do
		;カウンタに書き込む
			bsr	write_counters
		;秒テスト準備
			moveq.l	#$0F,dPL
			and.b	dWL,dPL
		;秒テスト開始
			di
			write_rtc	#1,RTC_TEST
		;1秒カウンタが変化するまで待つ
			do
				read_rtc	RTC_0_ONE_SECOND,dRL
			while	<cmp.b dPL,dRL>,eq
		;秒テスト終了
			write_rtc	#0,RTC_TEST
			ei
		;前回読み出した値をダミーに
			moveq.l	#-1,dPH
			moveq.l	#-1,dPL
		;読み出した値をダミーに
			moveq.l	#-1,dRH
			moveq.l	#-1,dRL
		;3回続けて同じ値が読み出されるまで繰り返す
			do
			;前回読み出した値を前々回読み出した値にコピー
				movea.l	dPH,aOH
				movea.l	dPL,aOL
			;読み出した値を前回読み出した値にコピー
				move.l	dRH,dPH
				move.l	dRL,dPL
			;カウンタから読み出す
				bsr	read_counters
			whileor	<cmp.l aOH,dRH>,ne,<cmp.l aOL,dRL>,ne
		;確認
			move.l	dWL,-(sp)
			move.l	dWH,-(sp)
			jbsr	increment
			move.l	(sp)+,dPH
			move.l	(sp)+,dPL
			breakand	<cmp.l dPH,dRH>,eq,<cmp.l dPL,dRL>,eq	;成功
			subq.w	#1,aTRY
			move.w	aTRY,d0
		while	pl
		if	eq			;成功
			addq.l	#1,passed_counter
		else				;失敗
			if	<tst.l failed_counter>,eq	;初回
			;ヘッダ表示
				lea.l	header_message,a0
				jbsr	print
			endif
			addq.l	#1,failed_counter
		;エラー表示
			lea.l	string_buffer,a0
		;input
			move.l	dWH,d0
			jbsr	h8tos
			move.b	#':',(a0)+
			move.l	dWL,d0
			jbsr	h8tos
		;expected output
			move.b	#' ',(a0)+
			move.l	dPH,d0
			jbsr	h8tos
			move.b	#':',(a0)+
			move.l	dPL,d0
			jbsr	h8tos
		;observed output
			move.b	#' ',(a0)+
			move.l	dRH,d0
			jbsr	h8tos
			move.b	#':',(a0)+
			move.l	dRL,d0
			jbsr	h8tos
			lea.l	error_message,a1
			jbsr	strcpy
			lea.l	string_buffer,a0
			jbsr	print
		endif
	;ドット表示
		subq.w	#1,dot_counter
		if	eq
			lea.l	dot_message,a0
			jbsr	print
		;カウンタ停止(念のため)
			clock_stop
			move.w	#100,dot_counter
		endif
	start
		movea.l	data_pointer,a0
		move.l	(a0)+,dWH
	while	pl

;カウンタ復元
;	気休め。時間がかかったぶん遅れるので修正すること
	move.l	saved_counters,dWH
	move.l	saved_counters+4,dWL
	bsr	write_counters

;カウンタ動作
	clock_start

;ユーザモード
	usermode

;結果表示
	lea.l	string_buffer,a0
	jbsr	crlf
	move.l	passed_counter,d0
	jbsr	utos
	lea.l	passed_message,a1
	jbsr	strcpy
	move.l	failed_counter,d0
	jbsr	utos
	lea.l	failed_message,a1
	jbsr	strcpy
	lea.l	string_buffer,a0
	jbsr	print

;終了
	DOS	_EXIT

;カウンタから読み出す
;>dRL.l:読み出した値(下位)
;>dRH.l:読み出した値(上位)
read_counters:
;カウンタから読み出す(上位)
	bank_1
	read_rtc	RTC_1_LEAP_YEAR,dRH	;_______L
	bank_0
	read_rtc	RTC_0_DAY_OF_WEEK,dT
	lsl.l	#4,dRH
	or.b	dT,dRH		;______LW
	read_rtc	RTC_0_TEN_YEARS,dT
	lsl.l	#4,dRH
	or.b	dT,dRH		;_____LWY
	read_rtc	RTC_0_ONE_YEAR,dT
	lsl.l	#4,dRH
	or.b	dT,dRH		;____LWYY
	read_rtc	RTC_0_TEN_MONTHS,dT
	lsl.l	#4,dRH
	or.b	dT,dRH		;___LWYYM
	read_rtc	RTC_0_ONE_MONTH,dT
	lsl.l	#4,dRH
	or.b	dT,dRH		;__LWYYMM
	read_rtc	RTC_0_TEN_DAYS,dT
	lsl.l	#4,dRH
	or.b	dT,dRH		;_LWYYMMD
	read_rtc	RTC_0_ONE_DAY,dT
	lsl.l	#4,dRH
	or.b	dT,dRH		;LWYYMMDD
;カウンタから読み出す(下位)
	bank_1
	read_rtc	RTC_1_TWENTY_FOUR,dRL	;_______t
	bank_0
	read_rtc	RTC_0_TEN_HOURS,dT
	lsl.l	#4,dRL
	or.b	dT,dRL		;______th
	read_rtc	RTC_0_ONE_HOUR,dT
	lsl.l	#4,dRL
	or.b	dT,dRL		;_____thh
	read_rtc	RTC_0_TEN_MINUTES,dT
	lsl.l	#4,dRL
	or.b	dT,dRL		;____thhm
	read_rtc	RTC_0_ONE_MINUTE,dT
	lsl.l	#4,dRL
	or.b	dT,dRL		;___thhmm
	read_rtc	RTC_0_TEN_SECONDS,dT
	lsl.l	#4,dRL
	or.b	dT,dRL		;__thhmms
	read_rtc	RTC_0_ONE_SECOND,dT
	lsl.l	#4,dRL
	or.b	dT,dRL		;_thhmmss
	rts

;カウンタに書き込む
;<dWL.l:書き込む値(下位)
;<dWH.l:書き込む値(上位)
write_counters:
;カウンタに書き込む(上位)
	bank_1
	rol.l	#4,dWH		;WYYMMDDL
	write_rtc	dWH,RTC_1_LEAP_YEAR
	bank_0
	rol.l	#4,dWH		;YYMMDDLW
	write_rtc	dWH,RTC_0_DAY_OF_WEEK
	rol.l	#4,dWH		;YMMDDLWY
	write_rtc	dWH,RTC_0_TEN_YEARS
	rol.l	#4,dWH		;MMDDLWYY
	write_rtc	dWH,RTC_0_ONE_YEAR
	rol.l	#4,dWH		;MDDLWYYM
	write_rtc	dWH,RTC_0_TEN_MONTHS
	rol.l	#4,dWH		;DDLWYYMM
	write_rtc	dWH,RTC_0_ONE_MONTH
	rol.l	#4,dWH		;DLWYYMMD
	write_rtc	dWH,RTC_0_TEN_DAYS
	rol.l	#4,dWH		;LWYYMMDD
	write_rtc	dWH,RTC_0_ONE_DAY
;カウンタに書き込む(下位)
	bank_1
	rol.l	#8,dWL		;hhmmss_t
	write_rtc	dWL,RTC_1_TWENTY_FOUR
	bank_0
	rol.l	#4,dWL		;hmmss_th
	write_rtc	dWL,RTC_0_TEN_HOURS
	rol.l	#4,dWL		;mmss_thh
	write_rtc	dWL,RTC_0_ONE_HOUR
	rol.l	#4,dWL		;mss_thhm
	write_rtc	dWL,RTC_0_TEN_MINUTES
	rol.l	#4,dWL		;ss_thhmm
	write_rtc	dWL,RTC_0_ONE_MINUTE
	rol.l	#4,dWL		;s_thhmms
	write_rtc	dWL,RTC_0_TEN_SECONDS
	rol.l	#4,dWL		;_thhmmss
	write_rtc	dWL,RTC_0_ONE_SECOND
	rts

;インクリメント
;	  0 1 2 3   4 5 6 7
;	$LWYYMMDD,$_thhmmss
;<4(sp).q:入力
;>4(sp).q:出力
increment:
regs	reg	d0-d2/a0
	push	regs
base = .sizeof.(regs)+4
	do
	;oneseco
		move.b	base+7(sp),d0		;ss
		moveq.l	#$0F,d1
		and.b	d0,d1
		eor.b	d1,d0
		lea.l	nine(pc),a0
		move.b	(a0,d1.w),d1
		moveq.l	#$0F,d2
		and.b	d1,d2
		or.b	d2,d0
		move.b	d0,base+7(sp)		;ss
		eor.b	d2,d1
		break	eq
	;tenseco
		move.b	base+7(sp),d0		;ss
		ror.b	#4,d0
		moveq.l	#$07,d1
		and.b	d0,d1
		eor.b	d1,d0
		lea.l	five(pc),a0
		move.b	(a0,d1.w),d1
		moveq.l	#$0F,d2
		and.b	d1,d2
		or.b	d2,d0
		rol.b	#4,d0
		move.b	d0,base+7(sp)		;ss
		eor.b	d2,d1
		break	eq
	;oneminu
		move.b	base+6(sp),d0		;mm
		moveq.l	#$0F,d1
		and.b	d0,d1
		eor.b	d1,d0
		lea.l	nine(pc),a0
		move.b	(a0,d1.w),d1
		moveq.l	#$0F,d2
		and.b	d1,d2
		or.b	d2,d0
		move.b	d0,base+6(sp)		;mm
		eor.b	d2,d1
		break	eq
	;tenminu
		move.b	base+6(sp),d0		;mm
		ror.b	#4,d0
		moveq.l	#$07,d1
		and.b	d0,d1
		eor.b	d1,d0
		lea.l	five(pc),a0
		move.b	(a0,d1.w),d1
		moveq.l	#$0F,d2
		and.b	d1,d2
		or.b	d2,d0
		rol.b	#4,d0
		move.b	d0,base+6(sp)		;mm
		eor.b	d2,d1
		break	eq
	;hour
		moveq.l	#$01,d0
		and.b	base+4(sp),d0		;_t
		lsl.w	#2,d0
		lea.l	hour(pc),a0
		movea.l	(a0,d0.w),a0		;hour_t0 .. hour_t1
		moveq.l	#$3F,d0
		and.b	base+5(sp),d0		;hh
		add.w	d0,d0
		move.w	(a0,d0.w),d0
		move.b	d0,base+5(sp)		;hh
		and.w	#$0100,d0
		break	eq
	;wday
		move.b	base+0(sp),d0		;LW
		moveq.l	#$07,d1
		and.b	d0,d1
		eor.b	d1,d0
		lea.l	wday(pc),a0
		or.b	(a0,d1.w),d0
		move.b	d0,base+0(sp)		;LW
	;mday
		moveq.l	#$30,d0
		and.b	base+0(sp),d0		;LW
		lsr.b	#4-2,d0
		lea.l	mday(pc),a0
		movea.l	(a0,d0.w),a0		;mday_l0 .. mday_l3
		moveq.l	#$1F,d0
		and.b	base+2(sp),d0		;MM
		lsl.w	#2,d0
		movea.l	(a0,d0.w),a0		;mday_28 .. mday_31
		moveq.l	#$3F,d0
		and.b	base+3(sp),d0		;DD
		add.w	d0,d0
		move.w	(a0,d0.w),d0
		move.b	d0,base+3(sp)		;DD
		and.w	#$0100,d0
		break	eq
	;mont
		moveq.l	#$1F,d0
		and.b	base+2(sp),d0		;MM
		add.w	d0,d0
		lea.l	mont(pc),a0
		move.w	(a0,d0.w),d0
		move.b	d0,base+2(sp)		;MM
		and.w	#$0100,d0
		break	eq
	;leap
		move.b	base+0(sp),d0		;LW
		ror.b	#4,d0
		moveq.l	#$03,d1
		and.b	d0,d1
		eor.b	d1,d0
		lea.l	leap(pc),a0
		or.b	(a0,d1.w),d0
		rol.b	#4,d0
		move.b	d0,base+0(sp)		;LW
	;oneyear
		move.b	base+1(sp),d0		;YY
		moveq.l	#$0F,d1
		and.b	d0,d1
		eor.b	d1,d0
		lea.l	nine(pc),a0
		move.b	(a0,d1.w),d1
		moveq.l	#$0F,d2
		and.b	d1,d2
		or.b	d2,d0
		move.b	d0,base+1(sp)		;YY
		eor.b	d2,d1
		break	eq
	;tenyear
		move.b	base+1(sp),d0		;YY
		ror.b	#4,d0
		moveq.l	#$0F,d1
		and.b	d0,d1
		eor.b	d1,d0
		lea.l	nine(pc),a0
		move.b	(a0,d1.w),d1
		moveq.l	#$0F,d2
		and.b	d1,d2
		or.b	d2,d0
		rol.b	#4,d0
		move.b	d0,base+1(sp)		;YY
		eor.b	d2,d1
	while	f
	pop
	rts

;カウンタ遷移表
nine:
;		  0    1    2    3    4    5    6    7
	.dc.b	$01, $02, $03, $04, $05, $06, $07, $08
;		  8    9    A    B    C    D    E    F
	.dc.b	$09, $10, $0B, $16, $0D, $14, $0F, $12
five:
;		  0    1    2    3    4    5    6    7
	.dc.b	$01, $02, $03, $04, $05, $10, $07, $12
hour_t0:
;		  00    01    02    03    04    05    06    07
	.dc.w	$001, $002, $003, $004, $005, $006, $007, $008
;		  08    09    0A    0B    0C    0D    0E    0F
	.dc.w	$009, $010, $00B, $016, $00D, $014, $00F, $012
;		  10    11    12    13    14    15    16    17
	.dc.w	$011, $020, $013, $026, $015, $024, $017, $02A
;		  18    19    1A    1B    1C    1D    1E    1F
	.dc.w	$019, $020, $01B, $026, $01D, $024, $01F, $022
;		  20    21    22    23    24    25    26    27
	.dc.w	$021, $022, $023, $024, $025, $026, $027, $028
;		  28    29    2A    2B    2C    2D    2E    2F
	.dc.w	$029, $030, $02B, $036, $02D, $034, $02F, $032
;		  30    31    32    33    34    35    36    37
	.dc.w	$031, $100, $033, $106, $035, $104, $037, $10A
;		  38    39    3A    3B    3C    3D    3E    3F
	.dc.w	$039, $100, $03B, $106, $03D, $104, $03F, $102
hour_t1:
;		  00    01    02    03    04    05    06    07
	.dc.w	$001, $002, $003, $004, $005, $006, $007, $008
;		  08    09    0A    0B    0C    0D    0E    0F
	.dc.w	$009, $010, $00B, $016, $00D, $014, $00F, $012
;		  10    11    12    13    14    15    16    17
	.dc.w	$011, $012, $013, $014, $015, $016, $017, $018
;		  18    19    1A    1B    1C    1D    1E    1F
	.dc.w	$019, $020, $01B, $026, $01D, $024, $01F, $022
;		  20    21    22    23    24    25    26    27
	.dc.w	$021, $022, $023, $100, $025, $026, $027, $10C
;		  28    29    2A    2B    2C    2D    2E    2F
	.dc.w	$029, $030, $02B, $112, $02D, $034, $02F, $116
;		  30    31    32    33    34    35    36    37
	.dc.w	$031, $032, $033, $110, $035, $036, $037, $11C
;		  38    39    3A    3B    3C    3D    3E    3F
	.dc.w	$039, $000, $03B, $102, $03D, $004, $03F, $106
hour:
	.dc.l	hour_t0,hour_t1
wday:
;		 0   1   2   3   4   5   6   7
	.dc.b	$1, $2, $3, $4, $5, $6, $0, $1
mday_28:
;		  00    01    02    03    04    05    06    07
	.dc.w	$001, $002, $003, $004, $005, $006, $007, $008
;		  08    09    0A    0B    0C    0D    0E    0F
	.dc.w	$009, $010, $00B, $016, $00D, $014, $00F, $012
;		  10    11    12    13    14    15    16    17
	.dc.w	$011, $012, $013, $014, $015, $016, $017, $018
;		  18    19    1A    1B    1C    1D    1E    1F
	.dc.w	$019, $020, $01B, $026, $01D, $024, $01F, $022
;		  20    21    22    23    24    25    26    27
	.dc.w	$021, $022, $023, $024, $025, $026, $027, $028
;		  28    29    2A    2B    2C    2D    2E    2F
	.dc.w	$101, $110, $103, $116, $105, $114, $107, $112
;		  30    31    32    33    34    35    36    37
	.dc.w	$031, $101, $033, $107, $035, $105, $037, $10B
;		  38    39    3A    3B    3C    3D    3E    3F
	.dc.w	$111, $101, $113, $107, $115, $105, $117, $103
mday_29:
;		  00    01    02    03    04    05    06    07
	.dc.w	$001, $002, $003, $004, $005, $006, $007, $008
;		  08    09    0A    0B    0C    0D    0E    0F
	.dc.w	$009, $010, $00B, $016, $00D, $014, $00F, $012
;		  10    11    12    13    14    15    16    17
	.dc.w	$011, $012, $013, $014, $015, $016, $017, $018
;		  18    19    1A    1B    1C    1D    1E    1F
	.dc.w	$019, $020, $01B, $026, $01D, $024, $01F, $022
;		  20    21    22    23    24    25    26    27
	.dc.w	$021, $022, $023, $024, $025, $026, $027, $028
;		  28    29    2A    2B    2C    2D    2E    2F
	.dc.w	$029, $101, $02B, $107, $02D, $105, $02F, $103
;		  30    31    32    33    34    35    36    37
	.dc.w	$031, $101, $033, $107, $035, $105, $037, $10B
;		  38    39    3A    3B    3C    3D    3E    3F
	.dc.w	$039, $101, $03B, $107, $03D, $105, $03F, $103
mday_30:
;		  00    01    02    03    04    05    06    07
	.dc.w	$001, $002, $003, $004, $005, $006, $007, $008
;		  08    09    0A    0B    0C    0D    0E    0F
	.dc.w	$009, $010, $00B, $016, $00D, $014, $00F, $012
;		  10    11    12    13    14    15    16    17
	.dc.w	$011, $012, $013, $014, $015, $016, $017, $018
;		  18    19    1A    1B    1C    1D    1E    1F
	.dc.w	$019, $020, $01B, $026, $01D, $024, $01F, $022
;		  20    21    22    23    24    25    26    27
	.dc.w	$021, $022, $023, $024, $025, $026, $027, $028
;		  28    29    2A    2B    2C    2D    2E    2F
	.dc.w	$029, $030, $02B, $036, $02D, $034, $02F, $032
;		  30    31    32    33    34    35    36    37
	.dc.w	$101, $101, $103, $107, $105, $105, $107, $10B
;		  38    39    3A    3B    3C    3D    3E    3F
	.dc.w	$109, $101, $10B, $107, $10D, $105, $10F, $103
mday_31:
;		  00    01    02    03    04    05    06    07
	.dc.w	$001, $002, $003, $004, $005, $006, $007, $008
;		  08    09    0A    0B    0C    0D    0E    0F
	.dc.w	$009, $010, $00B, $016, $00D, $014, $00F, $012
;		  10    11    12    13    14    15    16    17
	.dc.w	$011, $012, $013, $014, $015, $016, $017, $018
;		  18    19    1A    1B    1C    1D    1E    1F
	.dc.w	$019, $020, $01B, $026, $01D, $024, $01F, $022
;		  20    21    22    23    24    25    26    27
	.dc.w	$021, $022, $023, $024, $025, $026, $027, $028
;		  28    29    2A    2B    2C    2D    2E    2F
	.dc.w	$029, $030, $02B, $036, $02D, $034, $02F, $032
;		  30    31    32    33    34    35    36    37
	.dc.w	$031, $101, $033, $107, $035, $105, $037, $10B
;		  38    39    3A    3B    3C    3D    3E    3F
	.dc.w	$039, $101, $03B, $107, $03D, $105, $03F, $103
mday_l0:
;		     00       01       02       03       04       05       06       07
	.dc.l	mday_31, mday_31, mday_29, mday_31, mday_30, mday_31, mday_30, mday_31
;		     08       09       0A       0B       0C       0D       0E       0F
	.dc.l	mday_31, mday_30, mday_31, mday_30, mday_30, mday_30, mday_30, mday_30
;		     10       11       12       13       14       15       16       17
	.dc.l	mday_31, mday_30, mday_31, mday_30, mday_30, mday_30, mday_30, mday_30
;		     18       19       1A       1B       1C       1D       1E       1F
	.dc.l	mday_31, mday_30, mday_31, mday_30, mday_30, mday_30, mday_30, mday_30
mday_l1:
;		     00       01       02       03       04       05       06       07
	.dc.l	mday_31, mday_31, mday_28, mday_31, mday_30, mday_31, mday_30, mday_31
;		     08       09       0A       0B       0C       0D       0E       0F
	.dc.l	mday_31, mday_30, mday_31, mday_30, mday_30, mday_30, mday_30, mday_30
;		     10       11       12       13       14       15       16       17
	.dc.l	mday_31, mday_30, mday_31, mday_30, mday_30, mday_30, mday_30, mday_30
;		     18       19       1A       1B       1C       1D       1E       1F
	.dc.l	mday_31, mday_30, mday_31, mday_30, mday_30, mday_30, mday_30, mday_30
mday:
;		      0        1        2        3
	.dc.l	mday_l0, mday_l1, mday_l1, mday_l1
mont:
;		  00    01    02    03    04    05    06    07
	.dc.w	$001, $002, $003, $004, $005, $006, $007, $008
;		  08    09    0A    0B    0C    0D    0E    0F
	.dc.w	$009, $010, $00B, $016, $00D, $014, $00F, $012
;		  10    11    12    13    14    15    16    17
	.dc.w	$011, $012, $101, $104, $015, $016, $105, $108
;		  18    19    1A    1B    1C    1D    1E    1F
	.dc.w	$019, $000, $109, $104, $01D, $004, $10D, $100
leap:
;		 0   1   2   3
	.dc.b	$1, $2, $3, $0

;カウンタに書き込む値
;	$LWYYMMDD,$_thhmmss
COUNTER	.macro	L,W,YY,MM,DD,t,hh,mm,ss
		.dc.l	((L)<<28)+((W)<<24)+((YY)<<16)+((MM)<<8)+(DD)
		.dc.l	((t)<<24)+((hh)<<16)+((mm)<<8)+(ss)
	.endm
data_table:
;秒
	.irp	ss10,0,4,5,6,7
		.irp	ss1,0,8,9,10,11,12,13,14,15
			COUNTER	0,0,$00,$01,$01,1,$00,$00,(ss10<<4)+ss1
		.endm
	.endm
;分
	.irp	mm10,0,4,5,6,7
		.irp	mm1,0,8,9,10,11,12,13,14,15
			COUNTER	0,0,$00,$01,$01,1,$00,(mm10<<4)+mm1,$59
		.endm
	.endm
;12/24、時
	.irp	t,0,1
		hh:=$00
		.rept	$3F-$00+1
			COUNTER	0,0,$00,$01,$01,t,hh,$59,$59
			hh:=hh+1
		.endm
	.endm
;閏年、月、日
	.irp	L,0,1,2,3
		MM:=$00
		.rept	$1F-$00+1
			DD:=$00
			.rept	$3F-$00+1
				COUNTER	L,0,$00,MM,DD,1,$23,$59,$59
				DD:=DD+1
			.endm
			MM:=MM+1
		.endm
	.endm
;年
	.irp	yy10,0,8,9,10,11,12,13,14,15
		.irp	yy1,0,8,9,10,11,12,13,14,15
			COUNTER	0,0,(yy10<<4)+yy1,$12,$31,1,$23,$59,$59
		.endm
	.endm
;曜日
	.irp	W,0,5,6,7
		COUNTER	0,W,$00,$01,$01,1,$23,$59,$59
	.endm
;
	.dc.l	-1

title_message:
	.dc.b	'RTCのカウンタが実機と同じように遷移しているか確認します',13,10,0
header_message:
	.dc.b	'      入力         期待された出力    観測された出力',13,10
	.dc.b	'LWYYMMDD:_thhmmss LWYYMMDD:_thhmmss LWYYMMDD:_thhmmss',13,10,0
dot_message:
	.dc.b	'.',0
error_message:
	.dc.b	' 失敗',13,10,0
passed_message:
	.dc.b	' 成功, ',0
failed_message:
	.dc.b	' 失敗',13,10
	.dc.b	'時計を合わせてください',13,10,0
	.even

	.bss
	.even
passed_counter:
	.ds.l	1
failed_counter:
	.ds.l	1
saved_counters:
	.ds.l	2
data_pointer:
	.ds.l	1
dot_counter:
	.ds.w	1
string_buffer:
	.ds.b	256



	.text
	.even

;----------------------------------------------------------------
;改行をコピーする
;<a0.l:コピー先
;>a0.l:コピー先の0の位置
crlf::
	move.b	#13,(a0)+
	move.b	#10,(a0)+
	clr.b	(a0)
	rts

;----------------------------------------------------------------
;符号なし整数を16進数8桁の文字列に変換する
;<d0.l:符号なし整数
;<a0.l:バッファ。16進数8桁の文字列の先頭
;>a0.l:16進数8桁の文字列の末尾の0の位置
h8tos::
	push	d1-d2
	moveq.l	#8-1,d1
	for	d1
		rol.l	#4,d0
		moveq.l	#15,d2
		and.w	d0,d2
		move.b	100f(pc,d2.w),(a0)+
	next
	clr.b	(a0)
	pop
	rts

100:	.dc.b	'0123456789ABCDEF'

;----------------------------------------------------------------
;文字列を表示する
;<a0.l:文字列
print::
	push	d0
	jbsr	strlen
	move.l	d0,-(sp)
	move.l	a0,-(sp)
	move.w	#1,-(sp)
	DOS	_WRITE
	lea.l	(10,sp),sp
	pop
	rts

;----------------------------------------------------------------
;文字列をコピーする
;<a0.l:コピー先
;<a1.l:コピー元
;>a0.l:コピー先の0の位置
;>a1.l:コピー元の0の次の位置
strcpy::
	do
		move.b	(a1)+,(a0)+
	while	ne			;0でなければ繰り返す
	subq.l	#1,a0			;進み過ぎた分戻る
	rts

;----------------------------------------------------------------
;文字列の長さを数える
;<a0.l:文字列
;>d0.l:長さ
strlen::
	move.l	a0,d0			;d0=先頭
	do
		tst.b (a0)+
	while	ne			;0でなければ繰り返す
	subq.l	#1,a0			;進み過ぎた分戻る。a0=末尾
	exg.l	d0,a0			;d0=末尾,a0=先頭
	sub.l	a0,d0			;d0=末尾-先頭=長さ
	rts

;----------------------------------------------------------------
;32ビット符号なし整数を10進数の文字列に変換する
;<d0.l:符号なし整数
;<a0.l:バッファ。10進数の文字列の先頭
;>a0.l:10進数の文字列の末尾の0の位置
utos::
	if	<tst.l d0>,eq		;0
		move.b	#'0',(a0)+
	else				;0以外
		push	d0-d2/a1
		lea.l	utos_table(pc),a1
		do
			move.l	(a1)+,d1
		while	<cmp.l d1,d0>,lo	;引けるところまで進む。ゼロサプレス
		do
			moveq.l	#'0'-1,d2
			do
				addq.b	#1,d2
				sub.l	d1,d0
			while	hs			;引ける回数を数える
			move.b	d2,(a0)+
			add.l	d1,d0			;引き過ぎた分を加え戻す
			move.l	(a1)+,d1
		while	ne
		pop
	endif
	clr.b	(a0)
	rts

utos_table::
	.dc.l	1000000000
	.dc.l	100000000
	.dc.l	10000000
	.dc.l	1000000
	.dc.l	100000
	.dc.l	10000
	.dc.l	1000
	.dc.l	100
	.dc.l	10
	.dc.l	1
	.dc.l	0