フォト
無料ブログはココログ

MyList

« CH559picoでTOYOSHIKI-BASIC | トップページ | 慌てた »

2025年2月 9日 (日)

CH559picoでTOYOSHIKI-BASIC (2)

CH559picoをCH55xduinoで豊四季BASICを実装したら何か変なので調べてみた。
実行したプログラムは、8Qeen問題を解くプログラム↓
豊四季BASICはtiny-basicだから WHILE が無いので IF と GOTO でループしている。
昔はこんな書き方だったよなぁ...


1  REM 8Qreen
10 T=(1=1); F=(1=2)
20 D=F
30 N=1
40 FOR I=1 TO 8; @(I)=0; NEXT I
50 X=1;Y=2;@(1)=1
100 REM
100 GOSUB 2000; REM Check
110 REM if C=T then
110 IF C=F GOTO 140
120   @(Y)=X; Y=Y+1; X=1
130   REM if Y=9 goub PrintTable
130   IF Y=9 GOSUB 3000
140   REM if C#F endif
140   IF C#F GOTO 190
150   X=X+1
160   IF X=9 Y=Y-1; X=@(Y)+1; @(Y)=0
170   IF X=9 Y=Y-1; X=@(Y)+1; @(Y)=0
180   IF Y=0 GOTO 210; REM End
190   REM EndIf
190   IF D GOSUB 3000
200 GOTO 100
210 REM END
210 STOP

2000 REM
2010 IF Y=9 C=F; RETURN
2020 C=T
2030 FOR L=1 TO Y-1
2040   IF @(L)=X C=F
2050   IF @(L)-X=Y-L C=F
2060   IF X-@(L)=Y-L C=F
2070   IF D PRINT "X=",X," Y=",Y," @(",L,")=",@(L)," C=",C
2080   IF C=F L=Y-1
2090   NEXT L
2100   IF D PRINT "< ",X,",",Y,":",C
2110 RETURN

3000 REM
3010 PRINT "--- ",N," ---",
3020 IF D PRINT X,",",Y,
3030 PRINT
3040 FOR L=1 TO 8
3050   FOR M=1 TO 8
3060     REM IF Y#L then
3060     IF Y=L GOTO 3090
3070       IF @(L)=M PRINT "|Q",
3080       IF @(L)#M PRINT "| ",
3090     REM else
3090       IF Y#L GOTO 3120
3100       IF X=M PRINT "|-",
3110       IF X#M PRINT "| ",
3120     REM EndIf
3120   NEXT M
3130   PRINT "|"
3140 NEXT L
3150 PRINT
3160 IF D INPUT A
3170 N=N+1
3180 RETURN


2060 IF X-@(L)=Y-L C=F

この行は必ず Flaseになる?
豊四季BASIC linux版で↑のソースを動かすと正常に動く。

PEEK() 関数を実装して中間言語バッファをダンプしたら中間言語は正しく変化されているようだった。

1 PRINT REM ABC
2 PRINT I-@(J)

00 0B 01 00 08 05 22 41 42 43 22 2A 0D 02 00 0B
28 08 14 20 18 28 09 19 2A 17 28 00 0A 29 0E 53


bacic.cppのipuluse()の戻り値 value の値がおかしいことが判った。
5行目の imul(),20行目の imul()の戻り値は正しいが、25行目で 0を返してしまう?

 1: // add or subtract calculation
 2: short iplus() {
 3: short value, tmp; //値と演算値
 4:
 5: 
value = imul(); //値を取得
 6: if (err) //もしエラーが生じたら
 7:   return -1; //終了
 8:
 9: while (1) //無限に繰り返す
10:  switch(*cip){ //中間コードで分岐
11: 
12:   case I_PLUS: //足し算の場合
13:     cip++; //中間コードポインタを次へ進める
14:     tmp = imul(); //演算値を取得
15:     value += tmp; //足し算を実行
16:     break; //ここで打ち切る
17: 
18:  case I_MINUS: //引き算の場合
19:    cip++; //中間コードポインタを次へ進める
20:    tmp = imul(); //演算値を取得
21:    value -= tmp; //引き算を実行
22:    break; //ここで打ち切る
23:    
24:  default: //以上のいずれにも該当しなかった場合
25:     return value; //値を持ち帰る
26:  } //中間コードで分岐の末尾
27: }


↓ -@(L)+X のように書くと正しい答えになる?

2060 IF -@(L)+X=Y-L C=F

1週間くらい悩んでいたのだが、このページにヒントがあった。
8Qenn(2011/09/15)←自分のページかいっ!!

SDCCは関数を呼ぶときの引数はレジスタ渡しにしたり、関数内のローカル変数をレジスタに割付けたりする。
このような関数に再入すると変数を上書きしてしまう。
スタックを使用するにはコンパイル・オプション --satck-auto を指定する必要があるが、ライブラリも --stack-autoでコンパイルされている必要がある。
CH55xduinoのコンパイルオプションに --satck-auto を追加したら、CH55x用ライブラリがコンパイルできなかった。

関数を __reentrant 修飾すると、その関数は再入可能な関数になる。
ttbasic.cpp内の iexpから呼び出される関数を __reentrant 修飾したら、期待した結果になった。

20250125-143220

CH55xduinoのライブラリは --int-long-reent, --float-reentでコンパイルさてているらしいのが、--stack-autoではないらしいのでどこかで不具合が出るかもしれない。



最近の投稿】【最近のCPUボード】【最近のプログラミング】【2019の投稿】【2018の投稿】【2017の投稿】【2016の投稿】【2015の投稿

« CH559picoでTOYOSHIKI-BASIC | トップページ | 慌てた »

8031/8052 SBC」カテゴリの記事

Arduino」カテゴリの記事

CPUボード」カテゴリの記事

プログラミング」カテゴリの記事

コメント

コメントを書く

コメントは記事投稿者が公開するまで表示されません。

(ウェブ上には掲載しません)

« CH559picoでTOYOSHIKI-BASIC | トップページ | 慌てた »