MSX0 StackのベースとなっているM5 Stackは、BM8563というRTC(Real Time Clock)を内蔵しています。
MSX規格ではMSX2から時計を内蔵するようになり、時刻管理ができるようになりましたので、MSX0をMSX2以上のモードで動かせば、BM8563に時刻が書き込まれて利用される(GET TIME/GET DATEで取得する時刻として使える)のかなと思ってしまいそうですが、実はそうではありません。
ということは、BM8563はMSX0の通常機能には影響せずに独立して好きな用途に使うことができるということなのです。
BM8563は、IoT BASICではノードパス「"device/i2c_i/51"」でアクセスすることができます。
デバイスを初期化するには、00H,00H,01H,00H,0DH,00Hの順に値を送ります。
初期化後に、02Hに続いて、年、月、曜日、日、時、分、秒の順に値を送ります。
詳しくは、データシートなどをご覧いただきたいのですが、年については、1900年からの差分を記録しますが、2000年以降については、月の値のbit6(上から2桁目)を1にすると、2000年からの差分とみなされます。
曜日は0=日、1=月・・・です。
月以外の数値データについては、上位4ビットが10の位、下位4ビットが1の位になります。
で、MSX0本体の時計とは別に日時を管理できるようになって、じゃあどうするのって話ではあるのですが、MSX Origin Timeというのを勝手に考えてその時間を記録することにしました。MSX Origin TimeとはMSX企画が発表された1983年6月16日0時0分0秒からの差分時間になりますww
MSX Origin Timeを記録するほうのBASICプログラムはこちら。
1 'SAVE"SETMSXOT.BAS"
100 'Init
110 N0$="device/i2c_i"
120 BM$="51"
130 NP$=N0$+"/"+BM$
1000 'Find I2C Devices
1100 PRINT "BM8563(RTC) ";
1110 _IOTFIND(N0$,C)
1120 IF C=0 THEN PRINT "Not Found.":END
1200 _IOTFIND(N0$,A$(0),C)
1210 FOR I=0 TO C-1
1220 IF A$(I)=BM$ THEN PRINT "Found.":GOTO 2000
1230 NEXT I
1900 PRINT "Not Found.":END
2000 'BM8563 Initialize
2100 _IOTPUT(NP$,CHR$(&H0)+CHR$(&H0))
2110 _IOTPUT(NP$,CHR$(&H1)+CHR$(&H0))
2120 _IOTPUT(NP$,CHR$(&HD)+CHR$(&H0))
3000 YE=1983 :'Year
3010 MO=6 :'Month
3020 DW=4 :'Thursday
3030 DA=16 :'Date
3040 HO=0 :'Hour
3050 MI=0 :'Minute
3060 SE=0 :'Second
3100 GET DATE MD$
3110 GET TIME MT$
3200 Y1 = VAL("20"+MID$(MD$,1,2))-YE
3210 M2 = VAL(MID$(MD$,4,2))-MO+1
3230 IF M2<0 3240="" 3250="" 3260="" 3270="" 3280="" 3290="" 4100="" 4110="" 4130="" 4140="" 4195="" 4200="" 4210="" 4220="" b4="" ct="" d3="0" d4="30+D4:M2=M2-1:IF" dt="" ear="" h5="VAL(MID$(MT$,1,2))" hex="" if="" m2="" m6="VAL(MID$(MT$,4,2))" onth="" print="" s7="VAL(MID$(MT$,7,2))" then="" v="">=10 THEN B4$="1":M2=M2-10
4230 DT$=CHR$(VAL("&B"+CT$+"00"+B4$+"0000")+M2)+DT$
4235 PRINT HEX$(ASC(DT$))
4300 'Day of Week
4310 DT$=CHR$(D3)+DT$
4335 PRINT HEX$(ASC(DT$))
4400 'Date
4410 V$=STR$(D4):V$=RIGHT$(V$,LEN(V$)-1)
4420 DT$=CHR$(VAL("&H"+V$))+DT$
4435 PRINT HEX$(ASC(DT$))
4600 'Hour
4610 V$=STR$(H5):V$=RIGHT$(V$,LEN(V$)-1)
4620 DT$=CHR$(VAL("&H"+V$))+DT$
4630 PRINT HEX$(ASC(DT$))
4700 'Minute
4710 V$=STR$(M6):V$=RIGHT$(V$,LEN(V$)-1)
4720 DT$=CHR$(VAL("&H"+V$))+DT$
4735 PRINTHEX$(ASC(DT$))
4800 'Second
4810 V$=STR$(S7):V$=RIGHT$(V$,LEN(V$)-1)
4820 DT$=CHR$(VAL("&H"+V$))+DT$
4835 PRINT HEX$(ASC(DT$))
4900 FOR I=1 TO 7
4910 PRINT RIGHT$("0"+HEX$(ASC(MID$(DT$,I,1))),2);" ";
4920 NEXT I
4930 PRINT
5000 'Set Date
5010 PRINT "RTC Set To ";Y1;"/";M2;"/";D4;" ";H5;":";M6;":";S7;"..."
5100 _IOTPUT(NP$,CHR$(&H2)+DT$)
そして、通常の時計とMSX Origin Timeを表示するプログラムがこちらです。
1 'SAVE"MSXOTCLK.BAS"
100 'Init
110 N0$="device/i2c_i"
120 BM$="51"
130 NP$=N0$+"/"+BM$
200 FOR I=0 TO 6
210 READ DW$(I)
220 NEXT I
230 DATA Sun,Mon,Tue,Wed,Thu,Fri,Sat
500 SCREEN 1
1000 'Find I2C Devices
1100 PRINT "BM8563(RTC) ";
1110 _IOTFIND(N0$,C)
1120 IF C=0 THEN PRINT "Not Found.":END
1200 _IOTFIND(N0$,A$(0),C)
1210 FOR I=0 TO C-1
1220 IF A$(I)=BM$ THEN PRINT "Found.":GOTO 2000
1230 NEXT I
1900 PRINT "Not Found.":END
2000 'BM8563 Initialize
2100 _IOTPUT(NP$,CHR$(&H0)+CHR$(&H0))
2110 _IOTPUT(NP$,CHR$(&H1)+CHR$(&H0))
2120 _IOTPUT(NP$,CHR$(&HD)+CHR$(&H0))
2200 CLS
3000 'Get Date and Time From BM8563(RTC)
3100 GET DATE DM$
3110 GET TIME TM$
3200 FOR I=1 TO 7
3210 _IOTPUT(NP$,CHR$(I+1)):_IOTGET(NP$,D$)
3220 BX=ASC(D$)
3230 IF I=1 THEN BX=BX AND &H7F :'Second
3240 IF I=2 THEN BX=BX AND &H7F :'Minute
3250 IF I=3 THEN BX=BX AND &H3F :'Hour
3260 IF I=4 THEN BX=BX AND &H3F :'Date
3270 IF I=5 THEN BX=BX AND &H7 :'Day of Week
3280 IF I=6 THEN CF=BX AND &H80 : BX=BX AND &H1F :'Month
3300 IF CF<>0 THEN CT=2000 ELSE CT=1900
3400 BC$ = RIGHT$("0"+HEX$(BX),2)
3410 B = VAL("&H"+LEFT$(BC$,1))*10+VAL("&H"+RIGHT$(BC$,1))
3420 'IF I=7 THEN B=B+CT
3430 DT(I-1)=B
3450 'PRINT RIGHT$("0"+HEX$(ASC(D$)),2);" ";
3500 NEXT I
3510 'PRINT
4000 'Output MSX Origin time and Current Time
4100 LOCATE 2,7
4110 PRINT "MSX Origin Time is..."
4200 LOCATE 2,8
4210 PRINT USING "##/##/## ##:##:##";DT(6),DT(5),DT(3),DT(2),DT(1),DT(0)
4310 LOCATE 2,11
4320 PRINT "Current Time is..."
4400 LOCATE 2,12
4410 PRINT DM$;" ";TM$
5000 IF INKEY$="" THEN 3000
ちなみに、MSX Origin Timeの求め方(1983/6/16 00:00:00との差分の求め方)は、あくまでネタなので正確性などは気にしないでくださいww
ソースはGitHubにも載せました。
コメント
コメントを投稿