そうだLifeGameを作ろう(1)

無性にLifeGameが作りたくなる時があります。

早速作ってみたんですが、いまいティンとこないです。きっとJavaで作ったからですね、わかります。

Javaが駄目ならassemblerを使えばいいじゃない byマリー

という事でassemblerで作ってみようかなと思います。ちょっとCが混じるかもしれません。

準備

nasmとqemumacportsで取得。

$ sudo port install qemu
$ sudo port install nasm

gasかnasmか迷ったんですが、AT&T構文よりIntel構文の方が好きなのでnasmにしました。即値やレジスタの前に$,%をつけるのが面倒くさいのです。

LifeGameの表示はCPUエミュレータ(でVRAM直接操作)で行います。ということでqemuを導入。bochsとかvmwareでもよかったんですが、qemuにしてみました。特に理由はありません。

Hello,BIOS world!

いきなりLifeGame作れというのは無茶振りなので、定番のあの言葉を画面に表示する事から始めます。

PC(qemu)起動時、内部では次の様な事が起こっています。

  1. 起動ディスクの最初の512bytes(ブートセクタ)を読み込む
  2. ブートセクタの最後の2byteが0xaa55だったら、ブートセクタをメモリの0x7c00にロード
  3. 0x7c00にあるコードを実行

つまり先頭から511-512byte目が0xaa55(little endian)となるプログラムを起動ディスクにすれば、プログラムの最初の512bytes(1セクタ)がメモリの0x7c00にロードされ実行されます。

このようなプログラムをassemblerで書くとこんな感じです。

   org   0x7c00            ;実行時にプログラムが読み込まれるアドレス
   mov   ax, 0
   mov   si, msg
; 処理部分(ここにやりたい処理を実装する) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
loop:                      ;画面表示
   mov   al, [si]
   inc   si
   cmp   al, 0
   je    end
   mov   ah, 0x0e
   mov   bx,0x00
   int   0x10              ;1文字画面表示
   jmp   loop
end:                       ;無限Loop
   jmp   end
msg:                       ;message
   db    0x0a              ;改行コード
   db    "Hello, BIOS world!"
   db    0x0a
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
   times 0x1fe-($-$$) db 0 ;510byte目まで0で埋める
   dw    0xaa55            ;511-512byte目が0xaa55

nasmでアセンブルしてqemuで実行すると・・・

$ nasm hello_bios.nas -o hello_bios.img
$ qemu hello_bios.img

Hello, BIOS world! って表示できました。