[MSX0] MSX0 Stackに内蔵されているRTCをIoT BASICから利用する #MSX #MSX0 #M5Stack


MSX0 StackのベースとなっているM5 Stackは、BM8563というRTC(Real Time Clock)を内蔵しています。

MSX規格ではMSX2から時計を内蔵するようになり、時刻管理ができるようになりましたので、MSX0をMSX2以上のモードで動かせば、BM8563に時刻が書き込まれて利用される(GET TIME/GET DATEで取得する時刻として使える)のかなと思ってしまいそうですが、実はそうではありません。


このとおりで、MSX0は現状、時刻の保持にBM8563は使っていないのです。

ということは、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にも載せました。



コメント