<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Lazarus &#8211; EXPERTGIG</title>
	<atom:link href="https://expertgig.jp/tag/lazarus/feed/" rel="self" type="application/rss+xml" />
	<link>https://expertgig.jp</link>
	<description>工場IoT に特化したシステム開発</description>
	<lastBuildDate>Mon, 06 Apr 2026 04:38:20 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	
	<item>
		<title>Raspi Zero 2W ベアメタル開発 08 (VRAM描画解決 編)</title>
		<link>https://expertgig.jp/2025/06/19/raspi-zero-2w-%e3%83%99%e3%82%a2%e3%83%a1%e3%82%bf%e3%83%ab%e9%96%8b%e7%99%ba-08-vram%e6%8f%8f%e7%94%bb%e8%a7%a3%e6%b1%ba-%e7%b7%a8/</link>
					<comments>https://expertgig.jp/2025/06/19/raspi-zero-2w-%e3%83%99%e3%82%a2%e3%83%a1%e3%82%bf%e3%83%ab%e9%96%8b%e7%99%ba-08-vram%e6%8f%8f%e7%94%bb%e8%a7%a3%e6%b1%ba-%e7%b7%a8/#respond</comments>
		
		<dc:creator><![CDATA[Ariyuki Tano]]></dc:creator>
		<pubDate>Wed, 18 Jun 2025 23:42:18 +0000</pubDate>
				<category><![CDATA[マイコン]]></category>
		<category><![CDATA[情報発信基地]]></category>
		<category><![CDATA[Lazarus]]></category>
		<category><![CDATA[MZ-80]]></category>
		<category><![CDATA[Raspi Zero 2W]]></category>
		<category><![CDATA[Ultibo]]></category>
		<category><![CDATA[エミュレータ]]></category>
		<guid isPermaLink="false">https://expertgig.jp/?p=6093</guid>

					<description><![CDATA[先週は、VRAMイメージの描画で、VRAMの内容を一発表示する分には、まぁまぁ問題なかったのですが、描画Threadを回すと、画面がゴミだらけで、まともに表示されるまで何分も待つという不思議な現象に悩まされていました。  [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>先週は、VRAMイメージの描画で、VRAMの内容を一発表示する分には、まぁまぁ問題なかったのですが、描画Threadを回すと、画面がゴミだらけで、まともに表示されるまで何分も待つという不思議な現象に悩まされていました。</p>



<figure class="wp-block-image size-large is-resized"><img fetchpriority="high" decoding="async" width="1024" height="576" src="https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250613_214530-1-1024x576.jpg" alt="" class="wp-image-6096" style="width:480px;height:auto" srcset="https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250613_214530-1-1024x576.jpg 1024w, https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250613_214530-1-300x169.jpg 300w, https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250613_214530-1-768x432.jpg 768w, https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250613_214530-1-1536x864.jpg 1536w, https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250613_214530-1-2048x1153.jpg 2048w, https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250613_214530-1-800x450.jpg 800w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>その原因が、いわゆる V-Sync (垂直同期) の問題と思っていて、どうやって Raspi Zero 2Wから V-Sync完了の情報をもらうか、そしてどれだけ速く書き込むか (次のV-Syncまでの間に画面生成完了させる。) 、Double Buffer にしてどうするとか。。</p>



<p>さんざんいじくりまわした挙句、元に戻すこともできなくなり、前回の投稿のように Z80エミュレート部分のスピードアップにいそしんだというわけです。</p>



<p>まぁしかし、怪我の功名。Z80のスピードは3.5倍になっただけでなく、新たなアプローチで原因を探すきっかけとなり、見事解決。</p>



<p>結果からいうと、CPUのL1 キャッシュの問題でした。</p>



<p>どういうことかというと、現代のCPU は、プログラムを先読みしてキャッシュしたり分岐の予測をしりして動作スピードをアップさせているわけなんですが、その先読み部分のデータについては、画面描画プログラムは高速で随時書き換えているわけです。</p>



<p>ですから、CPUが先走って読み込んだあとに対象の部分をプログラムが書き換えているので、データの不整合がおきるわけですね。</p>



<p>その結果画面はゴミが残ったような状態になったり、文字が欠けていたりしたわけです。</p>



<p>そこで、VRAM書き換え直後に キャッシュクリアしたら、あっさり解決。勉強になりました。</p>



<figure class="wp-block-image size-large is-resized"><img decoding="async" width="889" height="1024" src="https://expertgig.jp/wp/wp-content/uploads/2025/06/image-15-889x1024.png" alt="" class="wp-image-6094" style="width:435px;height:auto" srcset="https://expertgig.jp/wp/wp-content/uploads/2025/06/image-15-889x1024.png 889w, https://expertgig.jp/wp/wp-content/uploads/2025/06/image-15-260x300.png 260w, https://expertgig.jp/wp/wp-content/uploads/2025/06/image-15-768x885.png 768w, https://expertgig.jp/wp/wp-content/uploads/2025/06/image-15.png 908w" sizes="(max-width: 889px) 100vw, 889px" /></figure>



<p><br></p>



<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<p class="responsive-video-wrap clr"><iframe title="Raspi Zero 2W で MZ80K emu 開発。VRAM描画もうまくいった件 #raspi #emulator #mz80 #ultibo" width="1200" height="675" src="https://www.youtube.com/embed/f58UqlGKObI?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></p>
</div></figure>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>https://expertgig.jp/2025/06/19/raspi-zero-2w-%e3%83%99%e3%82%a2%e3%83%a1%e3%82%bf%e3%83%ab%e9%96%8b%e7%99%ba-08-vram%e6%8f%8f%e7%94%bb%e8%a7%a3%e6%b1%ba-%e7%b7%a8/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Raspi Zero 2W ベアメタル開発 04 ( MZ80KのVRAM表示編)</title>
		<link>https://expertgig.jp/2025/06/08/raspi-zero-2w-%e3%83%99%e3%82%a2%e3%83%a1%e3%82%bf%e3%83%ab%e9%96%8b%e7%99%ba-mz80k%e3%81%aevram%e8%a1%a8%e7%a4%ba%e7%b7%a8/</link>
					<comments>https://expertgig.jp/2025/06/08/raspi-zero-2w-%e3%83%99%e3%82%a2%e3%83%a1%e3%82%bf%e3%83%ab%e9%96%8b%e7%99%ba-mz80k%e3%81%aevram%e8%a1%a8%e7%a4%ba%e7%b7%a8/#respond</comments>
		
		<dc:creator><![CDATA[Ariyuki Tano]]></dc:creator>
		<pubDate>Sat, 07 Jun 2025 15:33:22 +0000</pubDate>
				<category><![CDATA[マイコン]]></category>
		<category><![CDATA[情報発信基地]]></category>
		<category><![CDATA[Lazarus]]></category>
		<category><![CDATA[MZ-80]]></category>
		<category><![CDATA[Raspi Zero 2W]]></category>
		<category><![CDATA[Ultibo]]></category>
		<category><![CDATA[VRAM]]></category>
		<category><![CDATA[Z80]]></category>
		<category><![CDATA[エミュレータ]]></category>
		<guid isPermaLink="false">https://expertgig.jp/?p=6069</guid>

					<description><![CDATA[前回、画面へのキャラクタ描画はうまく行ったので、もっとエミュレータ開発に使づくように、今日はもう一歩前進してみましょう。 MZ80Kのメモリ領域全体は、8bitマシンということで、64KBとなります。 メモリ内容を保持す [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>前回、画面へのキャラクタ描画はうまく行ったので、もっとエミュレータ開発に使づくように、今日はもう一歩前進してみましょう。</p>



<p>MZ80Kのメモリ領域全体は、8bitマシンということで、64KBとなります。</p>



<pre class="wp-block-code"><code class="">unit mem;<br>interface<br>var<br>  memory: array[0..65535] of Byte;<br>implementation<br>end. </code></pre>



<p>メモリ内容を保持する unit として、上記のように準備しました。</p>



<p>ここに、MZ-80KのモニタROM (SP-1002) を読み込んでみましょう。</p>



<pre class="wp-block-code"><code class="">//==============================================================================<br>// Load MONITOR ROM<br>//==============================================================================<br>procedure LoadMonitorRom;<br>var<br>  FS: TFileStream;<br>  MonitorPath: string;<br>  I: Integer;<br>begin<br>  ConsoleWindowWriteLn(Console1, 'Waiting for drive...');<br><br>  // C:\ または fat:\ が使えるのを待つ<br>  while not DirectoryExists('C:\') and not DirectoryExists('fat:\') do<br>    Sleep(100);<br><br>  if DirectoryExists('C:\') then<br>    MonitorPath := 'C:\mon_rom'<br>  else<br>    MonitorPath := 'fat:\mon_rom';<br><br>  ConsoleWindowWriteLn(Console1, 'Drive is ready.');<br><br>  if FileExists(MonitorPath) then<br>  begin<br>    ConsoleWindowWriteLn(Console1, 'Loading monitor ROM file...');<br>    FS := TFileStream.Create(MonitorPath, fmOpenRead);<br>    FS.Read(MonitorRom, SizeOf(MonitorRom));<br>    FS.Free;<br>    ConsoleWindowWriteLn(Console1, 'Monitor ROM loaded successfully!');<br>  end<br>  else<br>  begin<br>    ConsoleWindowWriteLn(Console1, 'Monitor ROM file not found at ' + MonitorPath);<br>  end;<br><br>  // 読み込んだ内容を memory[] にコピー<br>  for I := 0 to SizeOf(MonitorRom) - 1 do<br>    memory[I] := MonitorRom[I];<br>end;                  </code></pre>



<p>メモリの先頭 $0000番地から4KBのモニタROMを読み込んでセットします。</p>



<p>今後、Z80のエミュレータがうまく動けば、このモニタ部分を実行して、VRAMへの初期表示もされることになります。</p>



<p>まだそこまでは行けないので、今回はVRAMとして割り当てられた $D000 からの1000byte の内容を画面に表示するところまでやってみましょう。</p>



<p>つまり画面表示部分だけ先にテストしておこうというわけです。</p>



<h2 class="wp-block-heading">VRAMの内容を画面に表示する</h2>



<p>とりあえずざっとソースプログラムを見てみましょう。</p>



<pre class="wp-block-code"><code class="">//==============================================================================<br>// スクリーン描画スレッド<br>//==============================================================================<br>procedure DrawScreenThread;<br>var<br>  FTimeValue : QWord;<br>  FTimeDis   : QWord;<br>  FStartVSync: QWord;<br>  FEndVSync  : QWord;<br>  FVSyncTime : QWord;<br>  Amin       : Integer;<br>  Asec       : Integer;<br>  DrawFreq   : Integer;<br>  i, j       : Integer;<br>begin<br>  // すでにスレッドが開始されていたら停止<br>  if Assigned(ScreenThread) then<br>  begin<br>    flgStop := True;<br>    ScreenThread.Terminate;<br>    FreeAndNil(ScreenThread);<br>  end;<br><br>  // スレッド開始<br>  flgStop := False;<br>  ScreenThread := TDrawScreenThread.Create(False); // False = 自動起動<br>  ScreenThread.FreeOnTerminate := False;<br>end;<br><br>//==============================================================================<br>// Draw Screen Thread Execeute<br>//==============================================================================<br>procedure TDrawScreenThread.Execute;<br>var<br>  FStartVSync, FEndVSync, FVSyncTime: QWord;<br>begin<br>  while not Terminated do<br>  begin<br>    FStartVSync := GetTickCount64;<br><br>    //if hw80.v_gate then<br>    if true then  // z80動かすまでの仮設定<br>    begin<br>      update_scrn;<br>    end<br>    else<br>    begin<br>      ClearScreenFast(BG);  // 事前定義された背景色<br>    end;<br><br>    FEndVSync := GetTickCount64;<br>    FVSyncTime := FEndVSync - FStartVSync;<br><br>    if SYNCTIME > FVSyncTime then<br>      Sleep(SYNCTIME - FVSyncTime);<br><br>    Sleep(1);<br>  end;<br>end;<br><br>//==============================================================================<br>// 画面アップデート処理  (v-blank) [書き換えが必要部分だけ画面を書き換える]<br>//==============================================================================<br>procedure update_scrn;<br>var<br>  i: Integer;<br>  CharCode: Byte;<br>  Row, Col: Integer;<br>begin<br>  for i := 0 to 999 do<br>  begin<br>    CharCode := Memory[$D000 + i];<br>    if ScrChar[i] &lt;> CharCode then<br>    begin<br>      Row := i div 40;<br>      Col := i mod 40;<br>      DrawCharToSurface(Col * 8, Row * 8, CharCode);<br>      ScrChar[i] := CharCode;<br>    end;<br>  end;<br>end;<br><br>//==============================================================================<br>// 指定した X,Y (40x25) にキャラを表示<br>//==============================================================================<br>procedure DrawCharToSurface(X, Y: Integer; CharCode: Byte);<br>var<br>  Line, Bit: Integer;<br>  Px, Py: Integer;<br>  Data: Byte;<br>  Color: LongWord;<br>begin<br>  for Line := 0 to 7 do<br>  begin<br>    Data := FontRom[CharCode * 8 + Line];<br>    for Bit := 0 to 7 do<br>    begin<br>      Px := X + Bit;<br>      Py := Y + Line;<br><br>      if (Data and (1 shl (7 - Bit))) &lt;> 0 then<br>        Color := FG<br>      else<br>        Color := BG;<br><br>      PutPixel(Px, Py, Color);<br>    end;<br>  end;<br>end;<br><br>//==============================================================================<br>// 点を描画<br>//==============================================================================<br>procedure PutPixel(X, Y: Integer; Color: LongWord);<br>var<br>  Offset: PtrUInt;<br>begin<br>  Offset := FBInfo.PixelAddr + Y * FBInfo.Pitch + X * 4;<br>  PLongWord(Pointer(Offset))^ := Color;<br>end;<br><br>//==============================================================================<br>// 画面を高速クリア<br>//==============================================================================<br>procedure ClearScreenFast(Color: LongWord);<br>var<br>  PixelPtr: PLongWord;<br>  Count: Integer;<br>begin<br>  PixelPtr := PLongWord(Pointer(FBInfo.PixelAddr));<br>  Count := (FBInfo.Pitch div 4) * FBInfo.Height;<br><br>  while Count > 0 do<br>  begin<br>    PixelPtr^ := Color;<br>    Inc(PixelPtr);<br>    Dec(Count);<br>  end;<br>end;                 </code></pre>



<p>画面を一定周期で更新するThread を定義して実行します。</p>



<p>Thead内から、update_scrn (画面の更新処理) を呼び出します。</p>



<p>update_scrn では、高速化のためVRAM 上の値が前回と違う部分だけ更新するようにしています。</p>



<p>この中で、指定のX,Y 座標に文字を書き込む処理 DrawCharToSurface(X,Y,CharCode) を呼びだしています。</p>



<p>DrawCharToSurfaceでは、フォントデータに基づいてドットで画像を生成 ( PutPixel) しています。</p>



<p>PutPixel では、文字単位ではなくドット単位で書き込む処理が記述されています。</p>



<p>このように階層的に処理をしています。</p>



<h2 class="wp-block-heading">ランダムな情報をVRAMに書き込む</h2>



<p>まだ Z80が動いていないので、VRAMエリアに情報が書き込まれない状態ですので、とりあえずVRAMエリアにランダムに値を書き込みます。</p>



<pre class="wp-block-code"><code class="">procedure FillVRAMWithRandomChars;<br>var<br>  i: Integer;<br>begin<br>  Randomize;<br>  for i := 0 to 999 do<br>  begin<br>    Memory[$D000 + i] := Random(256);  // ランダムなキャラクターコード（0〜255）<br>  end;<br>end;   </code></pre>



<p>これで、元データはできあ゛かりますので、テストしてみましょう。</p>



<p>それと、プログラムがちゃんと動作していることを確かめるため、MZ700風に背景を青にして描画するようにしてみましょう。</p>



<figure class="wp-block-image size-large"><img decoding="async" width="1024" height="576" src="https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250608_002026-1024x576.jpg" alt="" class="wp-image-6070" srcset="https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250608_002026-1024x576.jpg 1024w, https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250608_002026-300x169.jpg 300w, https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250608_002026-768x432.jpg 768w, https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250608_002026-1536x864.jpg 1536w, https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250608_002026-2048x1152.jpg 2048w, https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250608_002026-800x450.jpg 800w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>うまく行きました。</p>



<p>Z80部分もコンパイルできるところまでは修正したのですが、まだうまく動いていないので、とりあえず今日はVRAMの表示をスレッドでできたというところまで。</p>



<div class="wp-block-file"><a id="wp-block-file--media-11e68203-2e33-4c76-a816-bdaf13c6df1f" href="https://expertgig.jp/wp/wp-content/uploads/2025/06/VRAM_DRAW.zip">VRAM_DRAW</a><a href="https://expertgig.jp/wp/wp-content/uploads/2025/06/VRAM_DRAW.zip" class="wp-block-file__button wp-element-button" download aria-describedby="wp-block-file--media-11e68203-2e33-4c76-a816-bdaf13c6df1f">ダウンロード</a></div>



<p>今回は、Z80の実装とMZ80のハードウェア定義もすべてソースに含まれていますが、まだZ80の実装部分のテストができていないので、動作からは外しています。</p>



<p>しかし、Z80部分のDEBUGをどうやってやろうかな。今の開発のやり方だと、まともにデバッグできないので、Raspi の エミュレータを開発環境に絡めてやるしかないんだろうな。。また開発環境の設定を触るしかないね。</p>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>https://expertgig.jp/2025/06/08/raspi-zero-2w-%e3%83%99%e3%82%a2%e3%83%a1%e3%82%bf%e3%83%ab%e9%96%8b%e7%99%ba-mz80k%e3%81%aevram%e8%a1%a8%e7%a4%ba%e7%b7%a8/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Raspi Zero 2W ベアメタル開発 03 ( 画面描画テスト編)</title>
		<link>https://expertgig.jp/2025/06/07/raspi-zero-2w-%e3%83%99%e3%82%a2%e3%83%a1%e3%82%bf%e3%83%ab%e9%96%8b%e7%99%ba-03-%e7%94%bb%e9%9d%a2%e6%8f%8f%e7%94%bb%e3%83%86%e3%82%b9%e3%83%88%e7%b7%a8/</link>
					<comments>https://expertgig.jp/2025/06/07/raspi-zero-2w-%e3%83%99%e3%82%a2%e3%83%a1%e3%82%bf%e3%83%ab%e9%96%8b%e7%99%ba-03-%e7%94%bb%e9%9d%a2%e6%8f%8f%e7%94%bb%e3%83%86%e3%82%b9%e3%83%88%e7%b7%a8/#respond</comments>
		
		<dc:creator><![CDATA[Ariyuki Tano]]></dc:creator>
		<pubDate>Fri, 06 Jun 2025 20:28:29 +0000</pubDate>
				<category><![CDATA[IoT関連]]></category>
		<category><![CDATA[マイコン]]></category>
		<category><![CDATA[情報発信基地]]></category>
		<category><![CDATA[Lazarus]]></category>
		<category><![CDATA[MZ-80]]></category>
		<category><![CDATA[Raspi Zero 2W]]></category>
		<category><![CDATA[Ultibo]]></category>
		<category><![CDATA[エミュレータ]]></category>
		<guid isPermaLink="false">https://expertgig.jp/?p=6057</guid>

					<description><![CDATA[さて、前回は画面に文字を書きましたが、今度は MZ-80K のフォントデータ 8&#215;8 ドット 256文字 = 2048 byte のデータを読み込んで、FrameBuffer に直接書き込むテストをしてみます。 [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>さて、前回は画面に文字を書きましたが、今度は MZ-80K のフォントデータ 8&#215;8 ドット 256文字 = 2048 byte のデータを読み込んで、FrameBuffer に直接書き込むテストをしてみます。</p>



<h2 class="wp-block-heading">ファイルの読み込みの準備</h2>



<p>ファイルをmicroSDから読み込む想定で考えていきます。</p>



<p>調べたところ、uses には色々と追加しなければならない。</p>



<pre class="wp-block-code"><code class="">uses<br>  RaspberryPi3, // ← ここが機種名<br>  GlobalConst, GlobalTypes,<br>  Platform, Console, SysUtils,<br>  Framebuffer,   // HDMI出力のある場合<br>  BCM2837,       // SoC定義（Zero2Wならこちら）<br>  Classes,       // TFileStreamやTStringList用<br>  FileSystem,    // コアファイルシステム<br>  FATFS,         // FATファイルシステム<br>  MMC,           // SDカードアクセスの中核<br>  BCM2710,       // Raspberry Pi向けMMC実装<br>  BCMSDHOST;     // SD Hostドライバ    </code></pre>



<p>この後、画面出力もあるので、 Framebuffer も一緒に追加しますが、なんか色々と追加。参考資料がないとお手上げですね。</p>



<h2 class="wp-block-heading">ファイル読み込み</h2>



<p>Raspiでは、C:ドライブが規定のドライブになるらしい。またドライブの準備ができるまでは、C: が見つからないのでエラーになってしまうから、C:の読み込み準備ができるまで待つ。ベアメタルの場合はいきなり起動するので、こういった処理も必要なんですね。</p>



<pre class="wp-block-code"><code class="">procedure LoadFontRom;<br>var<br>  FS: TFileStream;<br>begin<br>  ConsoleWindowWriteLn(Console1, 'Waiting for C:\ drive...');<br>  while not DirectoryExists('C:\') do Sleep(100);<br>  ConsoleWindowWriteLn(Console1, 'C:\ is ready.');<br><br>  if FileExists('C:\cg_rom') then<br>  begin<br>    ConsoleWindowWriteLn(Console1, 'Loading font file...');<br>    FS := TFileStream.Create('C:\cg_rom', fmOpenRead);<br>    FS.Read(FontRom, SizeOf(FontRom));<br>    FS.Free;<br>    ConsoleWindowWriteLn(Console1, 'Font loaded successfully!');<br>  end<br>  else<br>  begin<br>    ConsoleWindowWriteLn(Console1, 'Font file not found.');<br>  end;<br>end;  </code></pre>



<p>今回は、Dlephi で開発した MZ-80K エミュの時に作成したフォントデータファイル [cg_rom] をそのまま使うことにする。</p>



<p>ちなみにフォントデータ用に配列を次のように定義している。</p>



<pre class="wp-block-code"><code class="">FontRom: array [0..2047] of Byte;       // キャラクタフォントデータ </code></pre>



<div class="wp-block-file"><a id="wp-block-file--media-b33b7c83-2f84-4b66-af58-28634ecafb95" href="https://expertgig.jp/wp/wp-content/uploads/2025/06/cg_rom.zip">cg_rom</a><a href="https://expertgig.jp/wp/wp-content/uploads/2025/06/cg_rom.zip" class="wp-block-file__button wp-element-button" download aria-describedby="wp-block-file--media-b33b7c83-2f84-4b66-af58-28634ecafb95">ダウンロード</a></div>



<p>こちらご自由にお使いください。</p>



<h2 class="wp-block-heading">フォントを画面に書き込む</h2>



<p>フォントを 16 × 16 で順番に並べ画面に書き込む。</p>



<pre class="wp-block-code"><code class="">procedure DrawFontGridFromProperties;<br>var<br>  FB: PFramebufferDevice;<br>  Props: TFramebufferProperties;<br>  BaseAddr: PtrUInt;<br>  ch, cx, cy, x, y, bit: Integer;<br>  PixelAddr: PLongWord;<br>begin<br>  FB := FramebufferDeviceGetDefault;<br>  FramebufferDeviceGetProperties(FB, @Props);<br><br>  // 画面クリア（黒）<br>  for y := 0 to Props.VirtualHeight - 1 do<br>    for x := 0 to Props.VirtualWidth - 1 do<br>    begin<br>      PixelAddr := PLongWord(Props.Address + y * Props.Pitch + x * 4);<br>      PixelAddr^ := COLOR_BLACK;<br>    end;<br><br>  // フォント描画（8x8）<br>  for ch := 0 to 255 do<br>  begin<br>    cx := ch mod 16;<br>    cy := ch div 16;<br><br>    for y := 0 to 7 do<br>      for bit := 0 to 7 do<br>        if (FontRom[ch * 8 + y] and (128 shr bit)) &lt;&gt; 0 then<br>        begin<br>          x := cx * 8 + bit;<br>          PixelAddr := PLongWord(Props.Address + (cy * 8 + y) * Props.Pitch + x * 4);<br>          PixelAddr^ := COLOR_WHITE;<br>        end;<br>  end;<br>end;    </code></pre>



<h2 class="wp-block-heading">コンパイルして実行</h2>



<p>先ほどの [cg_rom] をmicroSDのルートにコピーして、コンパイル済の kernel7.img もコピーして、実機を起動。</p>



<figure class="wp-block-video"><video height="720" style="aspect-ratio: 1280 / 720;" width="1280" controls src="https://expertgig.jp/wp/wp-content/uploads/2025/06/VID_20250607_045115.mp4"></video></figure>



<p>表示されたが、なにやら緑の線がいっぱい。でもしばらく放っておいたら落ち着いたのか、ちゃんと表示されました。</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="576" src="https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250607_045240-1024x576.jpg" alt="" class="wp-image-6060" srcset="https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250607_045240-1024x576.jpg 1024w, https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250607_045240-300x169.jpg 300w, https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250607_045240-768x432.jpg 768w, https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250607_045240-1536x864.jpg 1536w, https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250607_045240-2048x1152.jpg 2048w, https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250607_045240-800x450.jpg 800w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>準備が整うまで、少し待つというのが基本なのかな? ベアメタル。<br>ところで、このキャラクタの並びですがこれはディプレイコードというものです。MZ-80Kは、キャラクターコード (ASCIIコードみたいなもの) とディスプレイコードというのが別になっていて、プログラム中で扱う文字としてはキャラクターコードなのですが、VRAMに表示するときは、このディスプレイコードに基づいて表示されるのです。私も長年不思議におもっていましたし、小学生の時は意味が分かりませんでした。</p>



<p>エミュレータをつくる際に、マシンの回路図を見ていて思ったのが、当時はこの方式が回路をシンプルにするのに都合がよかったのでしょうね。上から、4段ずつみていくと、キーボードと対応しています。SHIFT + A で クローバーが表示されますし、カナモードにしてAキーを押すと「チ」が表示されます。そしてカナ文字の部分は海外バージョンでは、小文字や面白い記号が割り当てられています。キーを押したときにCGROMから読み出すのが簡単だったのでしょうね。またそれをディスプレイに展開するのも単純になったのだと思います。<br><br>下は、手持ちのMZ-80K2のメイン基板です。右中央で水色のコンデンサの左上にあるのが CPU (Z80) で、Z80の左に少し行くと、大きなIC がありますが、これが CG-ROM です。このROMを差し替えると、表示される文字が変わります。</p>



<figure class="wp-block-image size-full is-resized"><img loading="lazy" decoding="async" width="1440" height="2560" src="https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250607_060112-scaled.jpg" alt="" class="wp-image-6065" style="width:354px;height:auto"/></figure>



<figure class="wp-block-image size-large is-resized"><img loading="lazy" decoding="async" width="461" height="1024" src="https://expertgig.jp/wp/wp-content/uploads/2025/06/Screenshot_2025-06-07-06-01-41-924_com.google.android.apps_.photos-461x1024.jpg" alt="" class="wp-image-6066" style="width:283px;height:auto" srcset="https://expertgig.jp/wp/wp-content/uploads/2025/06/Screenshot_2025-06-07-06-01-41-924_com.google.android.apps_.photos-461x1024.jpg 461w, https://expertgig.jp/wp/wp-content/uploads/2025/06/Screenshot_2025-06-07-06-01-41-924_com.google.android.apps_.photos-135x300.jpg 135w, https://expertgig.jp/wp/wp-content/uploads/2025/06/Screenshot_2025-06-07-06-01-41-924_com.google.android.apps_.photos-768x1707.jpg 768w, https://expertgig.jp/wp/wp-content/uploads/2025/06/Screenshot_2025-06-07-06-01-41-924_com.google.android.apps_.photos-691x1536.jpg 691w, https://expertgig.jp/wp/wp-content/uploads/2025/06/Screenshot_2025-06-07-06-01-41-924_com.google.android.apps_.photos-922x2048.jpg 922w, https://expertgig.jp/wp/wp-content/uploads/2025/06/Screenshot_2025-06-07-06-01-41-924_com.google.android.apps_.photos.jpg 1080w" sizes="(max-width: 461px) 100vw, 461px" /></figure>



<p>あれ、CG-ROMの右側の掃除ができていなかった。</p>



<h2 class="wp-block-heading">プロジェクトソース全体</h2>



<pre class="wp-block-code"><code class="">program hellopi;<br><br>uses<br>  RaspberryPi3, // ← ここが機種名<br>  GlobalConst, GlobalTypes,<br>  Platform, Console, SysUtils,<br>  Framebuffer,   // HDMI出力のある場合<br>  BCM2837,       // SoC定義（Zero2Wならこちら）<br>  Classes,       // TFileStreamやTStringList用<br>  FileSystem,    // コアファイルシステム<br>  FATFS,         // FATファイルシステム<br>  MMC,           // SDカードアクセスの中核<br>  BCM2710,       // Raspberry Pi向けMMC実装<br>  BCMSDHOST;     // SD Hostドライバ<br><br><br>var<br>  Console1: TWindowHandle;<br>  FontRom: array [0..2047] of Byte;       // キャラクタフォントデータ<br><br>procedure InitFramebuffer320x200;<br>var<br>  FB: PFramebufferDevice;<br>  Props: TFramebufferProperties;<br>begin<br>  FB := FramebufferDeviceGetDefault;<br><br>  FillChar(Props, SizeOf(Props), 0);<br>  Props.PhysicalWidth := 320;<br>  Props.PhysicalHeight := 200;<br>  Props.VirtualWidth := 320;<br>  Props.VirtualHeight := 200;<br>  Props.Depth := 32;  // 32bit（ARGB）<br><br>  FramebufferDeviceSetProperties(FB, @Props);<br>end;<br><br>procedure LoadFontRom;<br>var<br>  FS: TFileStream;<br>begin<br>  ConsoleWindowWriteLn(Console1, 'Waiting for C:\ drive...');<br>  while not DirectoryExists('C:\') do Sleep(100);<br>  ConsoleWindowWriteLn(Console1, 'C:\ is ready.');<br><br>  if FileExists('C:\cg_rom') then<br>  begin<br>    ConsoleWindowWriteLn(Console1, 'Loading font file...');<br>    FS := TFileStream.Create('C:\cg_rom', fmOpenRead);<br>    FS.Read(FontRom, SizeOf(FontRom));<br>    FS.Free;<br>    ConsoleWindowWriteLn(Console1, 'Font loaded successfully!');<br>  end<br>  else<br>  begin<br>    ConsoleWindowWriteLn(Console1, 'Font file not found.');<br>  end;<br>end;<br><br>procedure DrawFontGridFromProperties;<br>var<br>  FB: PFramebufferDevice;<br>  Props: TFramebufferProperties;<br>  BaseAddr: PtrUInt;<br>  ch, cx, cy, x, y, bit: Integer;<br>  PixelAddr: PLongWord;<br>begin<br>  FB := FramebufferDeviceGetDefault;<br>  FramebufferDeviceGetProperties(FB, @Props);<br><br>  // 画面クリア（黒）<br>  for y := 0 to Props.VirtualHeight - 1 do<br>    for x := 0 to Props.VirtualWidth - 1 do<br>    begin<br>      PixelAddr := PLongWord(Props.Address + y * Props.Pitch + x * 4);<br>      PixelAddr^ := COLOR_BLACK;<br>    end;<br><br>  // フォント描画（8x8）<br>  for ch := 0 to 255 do<br>  begin<br>    cx := ch mod 16;<br>    cy := ch div 16;<br><br>    for y := 0 to 7 do<br>      for bit := 0 to 7 do<br>        if (FontRom[ch * 8 + y] and (128 shr bit)) &lt;&gt; 0 then<br>        begin<br>          x := cx * 8 + bit;<br>          PixelAddr := PLongWord(Props.Address + (cy * 8 + y) * Props.Pitch + x * 4);<br>          PixelAddr^ := COLOR_WHITE;<br>        end;<br>  end;<br>end;<br><br>begin<br>  Console1 := ConsoleWindowCreate(ConsoleDeviceGetDefault, 0, True);<br><br>  if Console1 &lt;&gt; -1 then<br>  begin<br>    ConsoleWindowWriteLn(Console1, 'Hello from Ultibo on Pi Zero 2 W!');<br>  end;<br><br>  InitFramebuffer320x200;<br>  LoadFontRom;<br>  DrawFontGridFromProperties;<br>  while True do Sleep(1000);<br>end.<br></code></pre>



<h2 class="wp-block-heading">プロジェクトファイル一式</h2>



<div class="wp-block-file"><a id="wp-block-file--media-b4eb4587-2ab4-4840-99c1-df65aeab5573" href="https://expertgig.jp/wp/wp-content/uploads/2025/06/DrawFont_Sample.zip">DrawFont_Sample</a><a href="https://expertgig.jp/wp/wp-content/uploads/2025/06/DrawFont_Sample.zip" class="wp-block-file__button wp-element-button" download aria-describedby="wp-block-file--media-b4eb4587-2ab4-4840-99c1-df65aeab5573">ダウンロード</a></div>



<p></p>



<h2 class="wp-block-heading">まとめ</h2>



<p>FrameBuffer への直接書き込みとファイルの読み込みテストができましたので、これで一気に目処が立ちましたね。</p>



<p>私は、新たな環境で開発を行う際に、まず文字の入出力、画面描画、キー入力、文字列の処理、データベースの読み書きなどのあたりを付けます。これらがうまく行けば、手足と羽がついたようなもので、あとは気兼ねなくプログラミングということになります。</p>



<p>プログラムの基本は、代入、条件分岐、繰り返し。これしかないんです。</p>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>https://expertgig.jp/2025/06/07/raspi-zero-2w-%e3%83%99%e3%82%a2%e3%83%a1%e3%82%bf%e3%83%ab%e9%96%8b%e7%99%ba-03-%e7%94%bb%e9%9d%a2%e6%8f%8f%e7%94%bb%e3%83%86%e3%82%b9%e3%83%88%e7%b7%a8/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		<enclosure url="https://expertgig.jp/wp/wp-content/uploads/2025/06/VID_20250607_045115.mp4" length="5614646" type="video/mp4" />

			</item>
		<item>
		<title>Raspi Zero 2W ベアメタル開発 02 (環境構築～Hello表示編)</title>
		<link>https://expertgig.jp/2025/06/07/raspi-zero-2w-%e3%83%99%e3%82%a2%e3%83%a1%e3%82%bf%e3%83%ab%e9%96%8b%e7%99%ba-02-%e7%92%b0%e5%a2%83%e6%a7%8b%e7%af%89%ef%bd%9ehello%e8%a1%a8%e7%a4%ba%e7%b7%a8/</link>
					<comments>https://expertgig.jp/2025/06/07/raspi-zero-2w-%e3%83%99%e3%82%a2%e3%83%a1%e3%82%bf%e3%83%ab%e9%96%8b%e7%99%ba-02-%e7%92%b0%e5%a2%83%e6%a7%8b%e7%af%89%ef%bd%9ehello%e8%a1%a8%e7%a4%ba%e7%b7%a8/#respond</comments>
		
		<dc:creator><![CDATA[Ariyuki Tano]]></dc:creator>
		<pubDate>Fri, 06 Jun 2025 15:08:10 +0000</pubDate>
				<category><![CDATA[IoT関連]]></category>
		<category><![CDATA[マイコン]]></category>
		<category><![CDATA[情報発信基地]]></category>
		<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Lazarus]]></category>
		<category><![CDATA[MZ-80]]></category>
		<category><![CDATA[Pascal]]></category>
		<category><![CDATA[Raspi Zero 2W]]></category>
		<category><![CDATA[Ultibo]]></category>
		<category><![CDATA[Z80]]></category>
		<category><![CDATA[エミュレータ]]></category>
		<guid isPermaLink="false">https://expertgig.jp/?p=6035</guid>

					<description><![CDATA[さて、意を決してから、右往左往して、ようやくHDMI 接続したモニタに文字を表示できましたので、そこまでの手順を手短に解説します。 Ultibo Core のダウンロード Lazarus IDE と統合された Ultib [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>さて、意を決してから、右往左往して、ようやくHDMI 接続したモニタに文字を表示できましたので、そこまでの手順を手短に解説します。</p>



<h2 class="wp-block-heading">Ultibo Core のダウンロード</h2>



<p>Lazarus IDE と統合された Ultibo は下記よりダウンロードします。</p>



<p>/<a href="https://ultibo.org/download/">https://ultibo.org/download/</a></p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="788" src="https://expertgig.jp/wp/wp-content/uploads/2025/06/image-1024x788.png" alt="" class="wp-image-6036" srcset="https://expertgig.jp/wp/wp-content/uploads/2025/06/image-1024x788.png 1024w, https://expertgig.jp/wp/wp-content/uploads/2025/06/image-300x231.png 300w, https://expertgig.jp/wp/wp-content/uploads/2025/06/image-768x591.png 768w, https://expertgig.jp/wp/wp-content/uploads/2025/06/image-1536x1182.png 1536w, https://expertgig.jp/wp/wp-content/uploads/2025/06/image.png 2008w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>2025/6/6 時点では、Ultibo-Core-2.6.049-Beetroot.exe が最新ですので、これをダウンロード。<br><br>もしくは、GitHub からもダウンロードできます。必要に応じて古いバージョンのダウンロードもできます。<br></p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="787" src="https://expertgig.jp/wp/wp-content/uploads/2025/06/image-1-1024x787.png" alt="" class="wp-image-6037" srcset="https://expertgig.jp/wp/wp-content/uploads/2025/06/image-1-1024x787.png 1024w, https://expertgig.jp/wp/wp-content/uploads/2025/06/image-1-300x231.png 300w, https://expertgig.jp/wp/wp-content/uploads/2025/06/image-1-768x590.png 768w, https://expertgig.jp/wp/wp-content/uploads/2025/06/image-1-1536x1181.png 1536w, https://expertgig.jp/wp/wp-content/uploads/2025/06/image-1.png 2014w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>こちらだと、少しサイズの大きい Ultibo-Core-2.6.049-Beetroot-Main.exe というのもあります。</p>



<p>私は、何か不足してもいやなので、こちらからダウンロードしました。</p>



<h2 class="wp-block-heading">インストール</h2>



<p>ダウンロードしたファイルを実行するとインストールが始まります。インストールディレクトリの指定などもできますが、とりあえずデフォルトのまま次へ次へと進みインストール。数分でインストールが完了します。</p>



<p>インストールが完了すると、C:\Ultibo\Core というフォルダができています。</p>



<figure class="wp-block-image size-large is-resized"><img loading="lazy" decoding="async" width="1024" height="842" src="https://expertgig.jp/wp/wp-content/uploads/2025/06/image-2-1024x842.png" alt="" class="wp-image-6038" style="width:455px;height:auto" srcset="https://expertgig.jp/wp/wp-content/uploads/2025/06/image-2-1024x842.png 1024w, https://expertgig.jp/wp/wp-content/uploads/2025/06/image-2-300x247.png 300w, https://expertgig.jp/wp/wp-content/uploads/2025/06/image-2-768x632.png 768w, https://expertgig.jp/wp/wp-content/uploads/2025/06/image-2.png 1075w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>C:\Ultibo\Core の下にこんなフォルダとファイルができていればとりあえずインストール成功かと思います。</p>



<h2 class="wp-block-heading">Lazarus (Ultibo Edition) を起動</h2>



<figure class="wp-block-image size-full is-resized"><img loading="lazy" decoding="async" width="339" height="353" src="https://expertgig.jp/wp/wp-content/uploads/2025/06/image-3.png" alt="" class="wp-image-6039" style="width:204px;height:auto" srcset="https://expertgig.jp/wp/wp-content/uploads/2025/06/image-3.png 339w, https://expertgig.jp/wp/wp-content/uploads/2025/06/image-3-288x300.png 288w" sizes="(max-width: 339px) 100vw, 339px" /></figure>



<p>Lazarus IDE (Ultibo Edition) を起動します。</p>



<p>初回の起動はFPC (free pascal ) のパスなどを設定する画面が表示されますが、デフォルトで設定されているので、開発環境のWindow のモードを選択するだけで良いでしょう。Windowモードは、Classic だと 昔風にそれぞれのウィンドが独立している形になっていて、今風だと、最近のDelphi風に1つのWindowにメニュー、プロジェクトインスペクタ、ソースエディタ、コードエクスプローラなどがドッキングされた感じになります。特に深い思い入れがなければ、今風のほうが良いでしょう。</p>



<p></p>



<figure class="wp-block-image size-large is-resized"><img loading="lazy" decoding="async" width="1024" height="690" src="https://expertgig.jp/wp/wp-content/uploads/2025/06/image-4-1024x690.png" alt="" class="wp-image-6040" style="width:567px;height:auto" srcset="https://expertgig.jp/wp/wp-content/uploads/2025/06/image-4-1024x690.png 1024w, https://expertgig.jp/wp/wp-content/uploads/2025/06/image-4-300x202.png 300w, https://expertgig.jp/wp/wp-content/uploads/2025/06/image-4-768x518.png 768w, https://expertgig.jp/wp/wp-content/uploads/2025/06/image-4-1536x1035.png 1536w, https://expertgig.jp/wp/wp-content/uploads/2025/06/image-4-2048x1380.png 2048w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>これは今風の場合。</p>



<h2 class="wp-block-heading">プロジェクトの作成</h2>



<p>メニューの[ファイル]→[新規] で下の画面が開きます。</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="605" src="https://expertgig.jp/wp/wp-content/uploads/2025/06/image-5-1024x605.png" alt="" class="wp-image-6041" srcset="https://expertgig.jp/wp/wp-content/uploads/2025/06/image-5-1024x605.png 1024w, https://expertgig.jp/wp/wp-content/uploads/2025/06/image-5-300x177.png 300w, https://expertgig.jp/wp/wp-content/uploads/2025/06/image-5-768x453.png 768w, https://expertgig.jp/wp/wp-content/uploads/2025/06/image-5.png 1128w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>今回は、Raspi Zero 2W をターゲットにしますので、これを選んで[OK] ボタンでプロジェクトが作成されます。</p>



<h2 class="wp-block-heading">プロジェクトオプションの設定</h2>



<figure class="wp-block-image size-full is-resized"><img loading="lazy" decoding="async" width="524" height="634" src="https://expertgig.jp/wp/wp-content/uploads/2025/06/image-6.png" alt="" class="wp-image-6042" style="width:237px;height:auto" srcset="https://expertgig.jp/wp/wp-content/uploads/2025/06/image-6.png 524w, https://expertgig.jp/wp/wp-content/uploads/2025/06/image-6-248x300.png 248w" sizes="(max-width: 524px) 100vw, 524px" /></figure>



<p>[プロジェクト] → [プロジェクトオプション] で下の画面が開きます。</p>



<figure class="wp-block-image size-large is-resized"><img loading="lazy" decoding="async" width="1024" height="679" src="https://expertgig.jp/wp/wp-content/uploads/2025/06/image-7-1024x679.png" alt="" class="wp-image-6043" style="width:683px;height:auto" srcset="https://expertgig.jp/wp/wp-content/uploads/2025/06/image-7-1024x679.png 1024w, https://expertgig.jp/wp/wp-content/uploads/2025/06/image-7-300x199.png 300w, https://expertgig.jp/wp/wp-content/uploads/2025/06/image-7-768x509.png 768w, https://expertgig.jp/wp/wp-content/uploads/2025/06/image-7.png 1208w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>[コンパイラオプション] → [設定と対象] で、対称プラットフォームは、上記画面のように設定してください。</p>



<p>ARMV7A 、RPIZERO2W がポイントです。設定したら[OK]ボタンで画面を閉じます。</p>



<h2 class="wp-block-heading">Hello world サンプルプログラムの作成</h2>



<pre class="wp-block-code"><code class="">program HelloPi;<br><br>uses<br>  RaspberryPi3, // ← ここが機種名<br>  GlobalConst, GlobalTypes,<br>  Platform, Console, SysUtils;<br><br>var<br>  Console1: TWindowHandle;<br><br>begin<br>  Console1 := ConsoleWindowCreate(ConsoleDeviceGetDefault, 0, True);<br><br>  if Console1 &lt;&gt; -1 then<br>  begin<br>    ConsoleWindowWriteLn(Console1, 'Hello from Ultibo on Pi Zero 2 W!');<br>  end;<br><br>  while True do Sleep(1000);<br>end.<br></code></pre>



<p>最初は何も考えずに、初期表示されているソースを消して、上記コードをペタッと貼り付けましょう!</p>



<h2 class="wp-block-heading">プロジェクトの保存</h2>



<p>まず最初にソースを保存してみましょうか。</p>



<p>Pascal は、ソースの先頭に書いた名前とファイル名が一致しないといけないので、 program hellopi; としたので、ファイルに名前を付けて保存で、 hellopi.lpr として保存してください。</p>



<p>とりあえず今は、このファイルしかないので、メニューの [プロジェクト] → [名前を付けてプロジェクト保存] で保存しても同じ結果かなと思います。 </p>



<figure class="wp-block-image size-full is-resized"><img loading="lazy" decoding="async" width="513" height="624" src="https://expertgig.jp/wp/wp-content/uploads/2025/06/image-8.png" alt="" class="wp-image-6044" style="width:216px;height:auto" srcset="https://expertgig.jp/wp/wp-content/uploads/2025/06/image-8.png 513w, https://expertgig.jp/wp/wp-content/uploads/2025/06/image-8-247x300.png 247w" sizes="(max-width: 513px) 100vw, 513px" /></figure>



<p>Pascal はこの他 unit というファイルもありまして、この後開発していく中で unit に分けて、uses で宣言して使うことになると思います。</p>



<h2 class="wp-block-heading">構築 (コンパイル + img出力)</h2>



<p>さていよいよ、コンパイルです。</p>



<figure class="wp-block-image size-full is-resized"><img loading="lazy" decoding="async" width="387" height="229" src="https://expertgig.jp/wp/wp-content/uploads/2025/06/image-10.png" alt="" class="wp-image-6046" style="width:194px;height:auto" srcset="https://expertgig.jp/wp/wp-content/uploads/2025/06/image-10.png 387w, https://expertgig.jp/wp/wp-content/uploads/2025/06/image-10-300x178.png 300w" sizes="(max-width: 387px) 100vw, 387px" /></figure>



<p>[構築] でコンパイルと Raspi 用の img ファイルができあがります。</p>



<figure class="wp-block-image size-large is-resized"><img loading="lazy" decoding="async" width="1024" height="104" src="https://expertgig.jp/wp/wp-content/uploads/2025/06/image-11-1024x104.png" alt="" class="wp-image-6047" style="width:601px;height:auto" srcset="https://expertgig.jp/wp/wp-content/uploads/2025/06/image-11-1024x104.png 1024w, https://expertgig.jp/wp/wp-content/uploads/2025/06/image-11-300x31.png 300w, https://expertgig.jp/wp/wp-content/uploads/2025/06/image-11-768x78.png 768w, https://expertgig.jp/wp/wp-content/uploads/2025/06/image-11.png 1061w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>こんな風に表示されたら、コンパイルは成功です。</p>



<p>出力先のフォルダ内をみてみましょう。</p>



<figure class="wp-block-image size-full is-resized"><img loading="lazy" decoding="async" width="164" height="254" src="https://expertgig.jp/wp/wp-content/uploads/2025/06/image-12.png" alt="" class="wp-image-6048" style="width:112px;height:auto"/></figure>



<p>このように出力されていれば成功かと思います。</p>



<h2 class="wp-block-heading">SDカードに書き込む</h2>



<p>先ほど生成された kernel7.img がこのプログラムの本体です。まずはこれをSDカードにコピーしましょう。</p>



<p>次に、 C:\Ultibo\Core\firmware\RPi3 のフォルダにある下の3つのファイルをSDカードにコピーします。</p>



<figure class="wp-block-image size-large is-resized"><img loading="lazy" decoding="async" width="1024" height="389" src="https://expertgig.jp/wp/wp-content/uploads/2025/06/image-13-1024x389.png" alt="" class="wp-image-6049" style="width:474px;height:auto" srcset="https://expertgig.jp/wp/wp-content/uploads/2025/06/image-13-1024x389.png 1024w, https://expertgig.jp/wp/wp-content/uploads/2025/06/image-13-300x114.png 300w, https://expertgig.jp/wp/wp-content/uploads/2025/06/image-13-768x291.png 768w, https://expertgig.jp/wp/wp-content/uploads/2025/06/image-13.png 1041w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>結果、SDカードの中身は、下のようになります。</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="200" height="191" src="https://expertgig.jp/wp/wp-content/uploads/2025/06/image-14.png" alt="" class="wp-image-6050"/></figure>



<h2 class="wp-block-heading">Raspi Zero に差して実行!</h2>



<figure class="wp-block-image size-large is-resized"><img loading="lazy" decoding="async" width="1024" height="576" src="https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250606_235558-1024x576.jpg" alt="" class="wp-image-6051" style="width:355px;height:auto" srcset="https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250606_235558-1024x576.jpg 1024w, https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250606_235558-300x169.jpg 300w, https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250606_235558-768x432.jpg 768w, https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250606_235558-1536x864.jpg 1536w, https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250606_235558-2048x1153.jpg 2048w, https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250606_235558-800x450.jpg 800w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>micro SD-CARD を Raspi に差して、HDMIケーブルとモニタを繋いで、電源コードを差し込めば、すぐに起動します。</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="576" src="https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250606_235603-1024x576.jpg" alt="" class="wp-image-6052" srcset="https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250606_235603-1024x576.jpg 1024w, https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250606_235603-300x169.jpg 300w, https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250606_235603-768x432.jpg 768w, https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250606_235603-1536x864.jpg 1536w, https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250606_235603-2048x1152.jpg 2048w, https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250606_235603-800x450.jpg 800w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="576" src="https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250606_235607-1024x576.jpg" alt="" class="wp-image-6053" srcset="https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250606_235607-1024x576.jpg 1024w, https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250606_235607-300x169.jpg 300w, https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250606_235607-768x432.jpg 768w, https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250606_235607-1536x864.jpg 1536w, https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250606_235607-2048x1153.jpg 2048w, https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250606_235607-800x450.jpg 800w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>さすがに、OS無しは起動が速い!</p>



<p>とりあえず、起動までできたので、次からはさっそくDelphi で書いた MZ-80K2 のエミュを移植したいと思います。</p>



<p>うん? まてよ。まだUSBキーボードのテストをしていなかった。こちらが先かな。</p>



<p>ということで、今回はここまで。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://expertgig.jp/2025/06/07/raspi-zero-2w-%e3%83%99%e3%82%a2%e3%83%a1%e3%82%bf%e3%83%ab%e9%96%8b%e7%99%ba-02-%e7%92%b0%e5%a2%83%e6%a7%8b%e7%af%89%ef%bd%9ehello%e8%a1%a8%e7%a4%ba%e7%b7%a8/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Raspi Zero 2W で ベアメタル開発 01 ( 情報調査編 )</title>
		<link>https://expertgig.jp/2025/06/02/raspi-zero-2w-%e3%81%a7-%e3%83%99%e3%82%a2%e3%83%a1%e3%82%bf%e3%83%ab%e9%96%8b%e7%99%ba/</link>
					<comments>https://expertgig.jp/2025/06/02/raspi-zero-2w-%e3%81%a7-%e3%83%99%e3%82%a2%e3%83%a1%e3%82%bf%e3%83%ab%e9%96%8b%e7%99%ba/#respond</comments>
		
		<dc:creator><![CDATA[Ariyuki Tano]]></dc:creator>
		<pubDate>Mon, 02 Jun 2025 14:22:09 +0000</pubDate>
				<category><![CDATA[マイコン]]></category>
		<category><![CDATA[情報発信基地]]></category>
		<category><![CDATA[Lazarus]]></category>
		<category><![CDATA[MZ-80]]></category>
		<category><![CDATA[Raspi Zero 2W]]></category>
		<category><![CDATA[エミュレータ]]></category>
		<guid isPermaLink="false">https://expertgig.jp/?p=6021</guid>

					<description><![CDATA[『ベアメタル』なかなか良い響きだ。私の好きなヘビーメタルに似ているがちょっと違う。 この単語を知ったのは、つい数年前のこと。Arduino や esp32 などの SBCを使って、うちの工場の設備情報を取得したり、何かを [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>『ベアメタル』なかなか良い響きだ。私の好きなヘビーメタルに似ているがちょっと違う。</p>



<p>この単語を知ったのは、つい数年前のこと。Arduino や esp32 などの SBCを使って、うちの工場の設備情報を取得したり、何かを出力したりといった実験を繰り返しているときに、だんだんスピードに物足りなさを感じてきた。また昔の話になってしまうが、初期のパソコン (マイコン) のBASICプログラムのスピードでは満足できなくなってマシン語で開発したくなる。そんな感じだ。RaspiでLinuxを動かして、その起動の遅さや実行スピードの遅さで、それを痛感した。</p>



<p>Arduino や esp32 などはそもそもメモリが少なかったり、CPUが非力で、やれることは限界があるので、Raspiをターゲットにしたいのだけど、RaspbianOS の上でPython でプログラミングなんて、かったるいの極致。</p>



<p>そこで、Armのマシン語の本を英語版で 2冊ほど買ってみた。さすがに RISCだけあって、単純な命令群なので、プログラムソースも単調な命令がひたすら並ぶ。これはちょっとつまらなそう。。などと考えながらWebで色々と検索していたら、「ベアメタル」という単語にたどり着いた。どうも OSを介さずに直接ハードをコントロールするプログラミングを「ベアメタル」というらしい。</p>



<p>何かおもしろそうな響きを感じ、いつか時間があればベアメタル開発をしてみたいなと思って、早数年が経過。</p>



<p>一方で、コロナ渦で、時間があったので、Windows 上で Delphi を使って MZ-80Kのエミュレータの開発なんてのもしてみた。こちらも一定の成果があったので、一気に開発したあとは放置していた。</p>



<p>さらに2024年の暮に、電波新聞社から PC-8801 mkIISR mini を開発中と発表され、それに合わせて、BASIC MAGAZINE DELUXE も販売するという。そして、なんと N88-BASIC や N-BASIC などのプログラムも募集するという情報を得て、一気にマイコン魂が目覚め、久々に Z80 でゲーム開発をしてしまった。</p>



<p>こうなってくると、私の気持ちのなかでは、マイコンブームとなり、一周めぐって MZ80のエミュレータをSBC で開発したい!! となったわけ。</p>



<p>それで、Raspi の ベアメタル開発を調べたら、なんと Lazarus IDE と統合された Ultibo ( ウルティボ ) というのがあるのを発見。Pascal で開発ということで、ここで自分の中ですべてが一本の線で結ばれた。</p>



<p>Raspi Zero 2W 上で動くMZ-80Kのエミュレータの開発を Delphi に酷似した Lazarus 環境で Pascal 言語を用いてベアメタル開発。</p>



<p>ちょっと長いタイトルだが、すべてを満たした。しかも、Raspi Zero 2W は HDMI で液晶表示もコントロールできるということで、これしかないと確信。</p>



<p>今日にいたったわけである。</p>



<p>とりあえず、ものをそろえてみた。</p>



<figure class="wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-1 is-layout-flex wp-block-gallery-is-layout-flex">
<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="576" data-id="6029" src="https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250602_221734-1-1024x576.jpg" alt="" class="wp-image-6029" srcset="https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250602_221734-1-1024x576.jpg 1024w, https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250602_221734-1-300x169.jpg 300w, https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250602_221734-1-768x432.jpg 768w, https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250602_221734-1-1536x864.jpg 1536w, https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250602_221734-1-2048x1152.jpg 2048w, https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250602_221734-1-800x450.jpg 800w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="576" data-id="6028" src="https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250602_221825-1-1024x576.jpg" alt="" class="wp-image-6028" srcset="https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250602_221825-1-1024x576.jpg 1024w, https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250602_221825-1-300x169.jpg 300w, https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250602_221825-1-768x432.jpg 768w, https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250602_221825-1-1536x864.jpg 1536w, https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250602_221825-1-2048x1153.jpg 2048w, https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250602_221825-1-800x450.jpg 800w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="576" data-id="6030" src="https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250602_221834-1-1024x576.jpg" alt="" class="wp-image-6030" srcset="https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250602_221834-1-1024x576.jpg 1024w, https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250602_221834-1-300x169.jpg 300w, https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250602_221834-1-768x432.jpg 768w, https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250602_221834-1-1536x864.jpg 1536w, https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250602_221834-1-2048x1153.jpg 2048w, https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250602_221834-1-800x450.jpg 800w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="576" data-id="6031" src="https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250602_222029-1-1024x576.jpg" alt="" class="wp-image-6031" srcset="https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250602_222029-1-1024x576.jpg 1024w, https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250602_222029-1-300x169.jpg 300w, https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250602_222029-1-768x432.jpg 768w, https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250602_222029-1-1536x864.jpg 1536w, https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250602_222029-1-2048x1152.jpg 2048w, https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250602_222029-1-800x450.jpg 800w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="576" data-id="6027" src="https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250602_222050-1-1024x576.jpg" alt="" class="wp-image-6027" srcset="https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250602_222050-1-1024x576.jpg 1024w, https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250602_222050-1-300x169.jpg 300w, https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250602_222050-1-768x432.jpg 768w, https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250602_222050-1-1536x864.jpg 1536w, https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250602_222050-1-2048x1152.jpg 2048w, https://expertgig.jp/wp/wp-content/uploads/2025/06/IMG_20250602_222050-1-800x450.jpg 800w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>
</figure>



<p>実機のディスプレイの表示領域とほぼ一緒の 4:3 の 8inch 液晶 と Raspi Zero 2W</p>



<p>きっとこれで、実寸大のMZ-80Kを、もう一度この手で再現できるかもしれない。そんな想像だけで、少し胸が躍る。</p>



<p>今はまだ、入口に立ったばかりだ。でも、この静かで穏やかな高揚感は、私にとってはじゅうぶんに意味のあるものだ。</p>



<p>言ってしまえば、ただの自己満足かもしれない。でも、人生の多くは、そういう満足の積み重ねでできているのだと思う。</p>



<p></p>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>https://expertgig.jp/2025/06/02/raspi-zero-2w-%e3%81%a7-%e3%83%99%e3%82%a2%e3%83%a1%e3%82%bf%e3%83%ab%e9%96%8b%e7%99%ba/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
