あーさん日記

https://akkera102.sakura.ne.jp/gbadev/ の中の人

Arduboy 実験36

fizzbuzzまで行きました・・・。いやー長かったです。


■メモ
arduinoのbufferを64byteから256byteに増やす - Qiita

・HardwareSerial.h
Serial.println(SERIAL_RX_BUFFER_SIZE, DEC);	// 64
Serial.println(SERIAL_TX_BUFFER_SIZE, DEC);	// 64

・USBAPI.h
Serial.println(SERIAL_BUFFER_SIZE, DEC);	// 64

HardwareSerialは上記2つ。Serialは3つ目だけを使用。
Serialだけしか使っていないのであんまり稼げないかな・・・。

Arduboy 実験35

フレームバッファを一切使わないで描画できるか調べてみました。
結論からいうと条件付きでできるものの、かなり微妙です。


簡単な擬似コードを書くと以下のようになります(SSD1306.pdf p34)。

void OledDrawDot(u8 x, u8 y)
{
	// set page Addressing Mode
	// 中略


	// command mode
	*pCs |=  csMask;
	*pDc &= ~dcMask;
	*pCs &= ~csMask;

	SPI.transfer(0xB0 | (y /  8));	// page start address
	SPI.transfer(0x00 | (x % 16));	// lower start column address
	SPI.transfer(0x10 | (x / 16));	// upper start column address


	// write mode
	*pCs |=  csMask;
	*pDc |=  dcMask;
	*pCs &= ~csMask;

	u8 s = これから書き込む縦8ドット分の現在の情報;	// ※注

	SPI.transfer((1 << (y % 8)) | s);
}

1回の書き込みは縦8ドット単位。問題は、変数sを用意できないことです。
SPI通信の場合、SSD1306のGDDRAMへ読み込みができません。

8.1.3 MCU Serial Interface (4-wire SPI) 
Under serial mode, only write operations are allowed.  

8.1.4 MCU Serial Interface (3-wire SPI)
Under serial mode, only write operations are allowed.  

Arduboyの接続が4か3かわからなかったので両方転記しました。どちらにしてもダメ。
たとえば

	OledDrawDot(0, 0);
	OledDrawDot(0, 3);

という順番で処理をすると、前に描画した0, 0のドットが消えます。
んー、8ドット単位づつの描画を許容するならいいですけど・・・。


あんまり役に立たない情報でした。

raspberry pi multiboot 実験2

wiringPiSPIでいけました。

#include <stdio.h>
#include <stdint.h>
#include <wiringPi.h>

void main(void)
{
	int r = wiringPiSPISetupMode(0, 100000, 3);
	printf("%d\n", r);

	uint8_t buf[4];

	printf("Looking for GBA\n");

	do
	{
		buf[0] = 0x00;
		buf[1] = 0x00;
		buf[2] = 0x62;
		buf[3] = 0x02;

		wiringPiSPIDataRW(0, &buf, 4);

		printf("r:0x%02x%02x%02x%02x\n", buf[0], buf[1], buf[2], buf[3]);
		usleep(10000);

	} while(buf[0] != 0x72 || buf[1] != 0x02 || buf[2] != 0x62 || buf[3] != 0x02);

	printf("Found GBA!\n");
}

mbedと比べてみると微妙に8bit目が長いです。とりあえず成功。
f:id:akkera102:20160520101221p:plain
ハマリポイントとしては待ち時間のところです。

usleep(1000000);

長すぎるとダメでした。

raspberry pi multiboot 実験1

とりあえずmbedの成功例。

//  mbed(LPC1768)   gba serial port(color)
//  p1-0V           6-GND (blue)
//  p5-mosi         3-SI  (orange)
//  p6-miso         2-SO  (red)
//  p7-sck          5-SC  (green)

#include "mbed.h"

LocalFileSystem local("local");
Serial pc(USBTX, USBRX);
SPI spi(p5, p6, p7);

int main(void) 
{
    spi.format(16, 3);
    spi.frequency(100000);

    uint16_t w1, w2;
    uint32_t w, r;

    pc.printf("Looking for GBA\n");

    do
    {
        w  = 0x00006202;
        w1 = w >> 16;
        w2 = w & 0xffff;

        r  = spi.write(w1) << 16;
        r  = spi.write(w2) | r;

        pc.printf("r:0x%08x\n", r);
        wait(0.01);

    } while(r != 0x72026202);

    pc.printf("Found GBA!\n");
}

■実行ログ
GBAはブートが完了してタイトルロゴが表示されている状態。mbedのリセットボタンを押した後のログ。

Looking for GBA
r:0x00000000
r:0xffffffff
r:0xffffffff
r:0xffffffff
r:0xffffffff
r:0xffffffff
r:0xffffffff
r:0xffffffff
r:0xffffffff
r:0xffffffff
r:0xffffffff
r:0xffffffff
r:0xffffffff
r:0xffffffff
r:0xffffffff
r:0xffffffff
r:0xffffffff
r:0xffffffff
r:0xffffffff
r:0xffffffff
r:0xffffffff
r:0xffffffff
r:0xffffffff
r:0xffffffff
r:0xffffffff
r:0x00000000
r:0x72026202
Found GBA!

■ロジアナ
r:0x00000000
f:id:akkera102:20160519195004p:plain
r:0x72026202
f:id:akkera102:20160519195013p:plain
普通ですよねー。

Arduboy 実験34

写経しつつ、変数の名前やらコードを変えてるのでのんびりやってます。
今更、Basicの成り立ちを読んでみました。

細かい差異はあるが、当時のものは概ね以下のような仕様であった。

・単純変数はA~Zの26個のみ。
・配列は@のみ。
・データ型は2バイト整数のみ。
・グラフィックやスクリーンエディットの機能はない。

Tiny BASIC - Wikipedia

豊四季タイニーBASICの基本機能を備えたものを公開します。
機能は次の2点をのぞいてパロアルトタイニーBASICと共通です。

第1に、記述の省略形がありません。
第2に、強制的な中断に使うキーは、(中略)[ESC]です。

ということでマニュアルを割愛します。

豊四季タイニーBASICのリファレンスを公開 | 電脳伝説 Vintagechips


ちょうどタイミングよく、Arduinoに移植をされている方が情報を公開して頂いてます。
豊四季タイニーBASIC Arduino版のフリーエリアを増やす実験(1) - Qiita


実験(2)のフリーエリアを増やすには?という項目。
やっぱりそうなっちゃうよなーというのが正直な感想です。

+const char kw0[] PROGMEM = "GOTO";
+const char kw1[] PROGMEM = "GOSUB";

(中略)

+const char * const kwtbl[] PROGMEM = {
+  kw0, kw1, kw2,

(以下略)

gccはほんと仕事してほしいです。
僕はこの書き方が好きではないのでメモリが増えてもいい、というトレードオフをしてるけど、
今回はこちらを採用しそうです。


ちなみにゴールは、以下のfuractal.bas(セルオートマトン)を動かすことにしました。
んー、PSET, DIMはないので手直ししないといけないなあ。

10  CLS 3
20  NX=239:NY=80
30  DIM X(240),Y(240)
35  REM --------------------------------
40  X(120)=1
50  PSET(120,0),1
55  REM --------------------------------
60  FOR K=1 TO NY-1
70    FOR I=120-K TO 120+K
80      Y(I)=(X(I-1)+X(I+1)+X(I)) MOD 2
90      PSET(I,K),Y(I)*7
100   NEXT
110   FOR I=0 TO NX
120     X(I)=Y(I)
130   NEXT
140 NEXT
145 REM --------------------------------
150 END

Arduboy 実験33

Basic作りは何回か挑戦しているのでうまく作れそうです。

void BasExecInit(void)
{
	OledDrawStr(0, 0, "TOYOSHIKI TINY Basic");
	OledDrawStr(0, 2, "Serial.available()");
	OledDrawStr(0, 3, "Waitting. Hit Any Key.");

	if(BasSerialIsAvailable() == TRUE)
	{
		OledDrawStr(0, 5, "Connect!");
		BasSerialFlush();

		Bas.act = BAS_EXEC_KEY;
	}
}