あーさん日記

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

リハビリ3

とりあえず最初のメッセージきました。
今日は技術書典5の開催日・・・なんですけど、諸事情で行けないのでbooth待ちです。
(できればpdfファイルでほしいなあ。。)

[NvSetScn 0000.scn]
[NvSetEvent 1]
000b [skip]
000c [day f0]
000e [jmpScn 33 1]

[NvSetScn 0033.scn]
[NvSetEvent 1]
002f [time f0]
0031 [flagSet [0] = 0]
0034 [PushB 33 2]
0038 [jmpScn 20 1]

[NvSetScn 0020.scn]
[NvSetEvent 1]
002b [PushA 20 2]
002f [If [ab] != 3 goto 4]
0033 [jmpScn 1 1]

[NvSetScn 0001.scn]
[NvSetEvent 1]
000b [msg 1]
[NvSetMsg 1]
004f [skip]
0050 [Bg fe]
0052 [skip]
0055 [light]
0057 [timeWait 64]
0059 [skip]
005a [季節はいつも、さりげなく通り過ぎていく。]

リハビリ1

例の移植、少しコードを書きました。
script.hを書くだけで2時間とかダメダメですねえ。


そういえば誰にいっているか不明な話を1つ。
えーと、なんで8ad使っているかという話ですけど、それ以外選択肢がなかったからです。
oggデコーダあれば使用していたのですけどコードがオープンでないというか。
昔、pogoshell pluginであったのは確認しているのですけどね。


oggの知識があって、GBAの仕様を把握して、かつコードを公開してくれるって
2018年ではレアすぎます。そこまでパワーある人ってgithub上でもいないというか。
あとmodかmmlと絡めてドライバ開発本とか書いてくれないかなーとか。


GBA開発は直線的にゲーム作りが進むかというとそうではなくて、
自分なりにテストコード書いて確認する作業もいるしで前に進みずらいですねえ。

raspi環境の整え GBA xxブート

■PC側
共有フォルダ経由でコピー。

copy test.gba \\raspberrypi\pi\multiboot\test.gba


■raspi側
1秒おきに監視。ファイルが更新されたら自動起動

#!/bin/sh


echo "multiboot watch..."
last=`ls --full-time test.gba | awk '{print $6"-"$7}'`

while true; do
        sleep 1
        current=`ls --full-time test.gba | awk '{print $6"-"$7}'`

        if [ $last != $current ] ; then
                echo ""
                echo "updated: $current"
                last=$current
                ./multiboot test.gba
        fi
done


GBA
電源入れなおし。


raspi 3 b+。wifiも内蔵されてますしraspi-configで設定できるしで
すごい簡単になりましたねー。


参考リンク:
ターミナルでサクッとファイル監視して自動実行させるスクリプト

FLASH(SST39VF040)メモ

9/27 少しコードを直しました。
f:id:akkera102:20180925224857p:plain
・書き込みコマンドにnopは必要みたいです。ない場合はうまくいきませんでした。
・EWRAMで作りましたけどIWRAMだとウェイトでうまくいかないかもしれません(特にnop部分)。
 ID取得に0xffが帰ってきたらもっとウェイトが必要です。
・セーブ個数はセクタ単位(0x0 - 0xf)なので1+15個(フラグ管理+しおり)が妥当のようです。
・1セクタ0x1000バイト。容量多くて助かります。
・REG_WSCNT = 0x4317(8 cycles)
・データーシート http://ww1.microchip.com/downloads/en/DeviceDoc/20005023B.pdf


宿題ようやく終わりました・・・たぶん。

#include "flash.h"
#include "libmy/bg.h"

//---------------------------------------------------------------------------
EWRAM_CODE void FlashInit(void)
{
	BgDrawScreen();
	BgDrawStrCls();

	BgDrawStr(0, 0, "MemoryBackupCubic Test");
}
//---------------------------------------------------------------------------
EWRAM_CODE void FlashExec(void)
{
	if(FlashIsExist() == FALSE)
	{
		for(;;){}
	}

	BgDrawPrintf(2, 1, "Type : Flash");
	BgDrawPrintf(2, 2, "Id   : %x", FlashGetId());

	BgDrawPrintf(2, 4, "Erase 0, 1, 2");
	FlashEraseSector(0);
	FlashEraseSector(1);
	FlashEraseSector(2);

	FlashByte(0x0000, 1);
	FlashByte(0x0001, 2);
	FlashByte(0x0002, 3);

	FlashByte(0x1000, 4);
	FlashByte(0x1001, 5);
	FlashByte(0x1002, 6);

	FlashByte(0x2000, 7);
	FlashByte(0x2001, 8);
	FlashByte(0x2002, 9);

	BgDrawPrintf(3,  5, "%x %x %x", FlashRead(0x0000), FlashRead(0x0001), FlashRead(0x0002));
	BgDrawPrintf(3,  6, "%x %x %x", FlashRead(0x1000), FlashRead(0x1001), FlashRead(0x1002));
	BgDrawPrintf(3,  7, "%x %x %x", FlashRead(0x2000), FlashRead(0x2001), FlashRead(0x2002));

	BgDrawPrintf(2,  8, "Erase 1");
	FlashEraseSector(1);

	BgDrawPrintf(3,  9, "%x %x %x", FlashRead(0x0000), FlashRead(0x0001), FlashRead(0x0002));
	BgDrawPrintf(3, 10, "%x %x %x", FlashRead(0x1000), FlashRead(0x1001), FlashRead(0x1002));
	BgDrawPrintf(3, 11, "%x %x %x", FlashRead(0x2000), FlashRead(0x2001), FlashRead(0x2002));

	BgDrawPrintf(2, 12, "Erase Chip");
	FlashEraseChip();

	BgDrawPrintf(3, 13, "%x %x %x", FlashRead(0x0000), FlashRead(0x0001), FlashRead(0x0002));
	BgDrawPrintf(3, 14, "%x %x %x", FlashRead(0x1000), FlashRead(0x1001), FlashRead(0x1002));
	BgDrawPrintf(3, 15, "%x %x %x", FlashRead(0x2000), FlashRead(0x2001), FlashRead(0x2002));

	BgDrawPrintf(2, 16, "Done");
}
//---------------------------------------------------------------------------
EWRAM_CODE void FlashByte(u16 adr, u8 dat)
{
	// Byte-Program
	FlashWrite(0x5555, 0xAA);
	FlashWrite(0x2AAA, 0x55);
	FlashWrite(0x5555, 0xA0);
	FlashWrite(adr, dat);

	FlashWait20us();
}
//---------------------------------------------------------------------------
EWRAM_CODE void FlashEraseChip(void)
{
	// Chip-Erase
	FlashWrite(0x5555, 0xAA);
	FlashWrite(0x2AAA, 0x55);
	FlashWrite(0x5555, 0x80);
	FlashWrite(0x5555, 0xAA);
	FlashWrite(0x2AAA, 0x55);
	FlashWrite(0x5555, 0x10);

	FlashWait100ms();
}
//---------------------------------------------------------------------------
EWRAM_CODE void FlashEraseSector(u16 sec)
{
	_ASSERT(sec < 0x10);


	// Sector-Erase
	FlashWrite(0x5555, 0xAA);
	FlashWrite(0x2AAA, 0x55);
	FlashWrite(0x5555, 0x80);
	FlashWrite(0x5555, 0xAA);
	FlashWrite(0x2AAA, 0x55);
	FlashWrite(sec * 0x1000, 0x30);

	FlashWait25ms();
}
//---------------------------------------------------------------------------
// SST39VF010 : BF D5
// SST39VF020 : BF D6
// SST39VF040 : BF D7
EWRAM_CODE u16 FlashGetId(void)
{
	// ID Entry
	FlashWrite(0x5555, 0xAA);
	FlashWrite(0x2AAA, 0x55);
	FlashWrite(0x5555, 0x90);

	// Read ID
	u8 id0 = FlashRead(0x0000);
	u8 id1 = FlashRead(0x0001);

	// ID Exit
	FlashWrite(0x5555, 0xAA);
	FlashWrite(0x2AAA, 0x55);
	FlashWrite(0x5555, 0xF0);

	return id0 | (id1 << 8);
}
//---------------------------------------------------------------------------
EWRAM_CODE void FlashWrite(u16 adr, u8 cmd)
{
	u8* p = (u8*)SRAM + adr;

	*p = cmd;

	__asm("NOP");
}
//---------------------------------------------------------------------------
EWRAM_CODE u8 FlashRead(u16 adr)
{
	u8* p = (u8*)SRAM + adr;

	u8 ret = *p;

	return ret;
}
//---------------------------------------------------------------------------
EWRAM_CODE void FlashWait20us(void)
{
	for(vu32 i=0; i<400; i++)
	{
		// 1週 大雑把に0.0625us(1clk = 16Mhz)
		__asm("NOP");
	}
}
//---------------------------------------------------------------------------
EWRAM_CODE void FlashWait25ms(void)
{
	for(vu32 i=0; i<3; i++)
	{
		// 1週 16.743ms
		while(REG_VCOUNT >= 160) {};
		while(REG_VCOUNT <  160) {};
	}
}
//---------------------------------------------------------------------------
EWRAM_CODE void FlashWait100ms(void)
{
	for(vu32 i=0; i<10; i++)
	{
		// 1週 16.743ms
		while(REG_VCOUNT >= 160) {};
		while(REG_VCOUNT <  160) {};
	}
}
//---------------------------------------------------------------------------
EWRAM_CODE bool FlashIsExist(void)
{
	u8 t1 = FlashRead(0x7FFF);
	u8 t2 = ~t1;

	FlashWrite(0x7FFF, t2);

	if(FlashRead(0x7FFF) != t2)
	{
		FlashWrite(0x7FFF, t1);

		return TRUE;
	}

	return FALSE;
}

さらに追記:
リハビリ14 - GBAプログラミング跡地