GA-1280Aの開発

PC-9801のCバスのグラフィックアクセラレータIO DATA GA-1280AはDOS上での開発キットが用意されていました。

GA-1280AはGA-1024Aの後継でビデオメモリが1Mから2Mにアップグレードしています。

現在もIO DATAのサイトにサポートソフトのファイルがありダウンロードできます。

https://www.iodata.jp/lib/software/g/106.htm

ダウンロードできるga360.exeは実行ファイルですが、中身はlhaの自己解凍ファイルです。

FreeBSDのlhasaで見てみるとこんな感じです。

```
 % lhasa ga360.exe 
 PERMSSN    UID  GID      SIZE  RATIO     STAMP           NAME
---------- ----------- ------- ------ ------------ --------------------
[generic]                 1165  49.4% Jan 30  1997 !
[generic]                 6082  32.7% Jan 30  1997 readme.txt
[generic]               650129 100.0% Jan 30  1997 disk1.exe
[generic]               207506 100.0% Jan 30  1997 disk2.exe
---------- ----------- ------- ------ ------------ --------------------
 Total         4 files  864882  99.5% Mar 18 11:08
```


disk2.exeがライブラリやサンプルコードなのでこれを取り出します。


```
% lhasa e ga360.exe disk2.exe
disk2.exe       - Melted   :  oooooooooooooooooooooooooo
```

disk2.exeも同じようにlhaの自己解凍ファイルなので、lhasaで解凍できます。

```
 % lhasa e disk2.exe 
include/gagraph.h       - Melted   :  o
msc/galib.lib   - Melted   :  oooooooo
sample/makemsc  - Melted   :  o
sample/maketc   - Melted   :  o
sample/sub.asm  - Melted   :  o
sample/bmpload.c        - Melted   :  oo
sample/bmpsave.c        - Melted   :  o
sample/rgbld16.c        - Melted   :  o
sample/rgbload.c        - Melted   :  oo
sample/sample.c - Melted   :  oo
sample/tiffload.c       - Melted   :  oo
sample/x68load.c        - Melted   :  oo
sample/gatext.com       - Melted   :  oo
sample/bmpload.exe      - Melted   :  ooo
sample/bmpsave.exe      - Melted   :  oooo
sample/jpegload.exe     - Melted   :  oooo
sample/rgbld16.exe      - Melted   :  oooooo
sample/rgbload.exe      - Melted   :  ooooo
sample/sample.exe       - Melted   :  ooooooo
sample/tiffload.exe     - Melted   :  oooo
sample/x68load.exe      - Melted   :  oooooo
turboc/galib.lib        - Melted   :  ooooooooo
gainit.doc      - Melted   :  oo
gainit.exe      - Melted   :  oooo
galib.doc       - Melted   :  oooooo
gaoff.com       - Melted   :  o
gaon.com        - Melted   :  o
readme.doc      - Melted   :  oo
```

ファイルはSJISで改行がCR+LFなのでUTF-8,LFに変換したほうが処理しやすいです。

ライブラリはMSCとTurbo C用のものが用意されているのでOpen Watcom v2のTurbo C互換モードでビルドしてみます。

sample.cをコンパイルしてみますが、ヘッダーが足りないので、追加します。

```c:
#include <stdio.h>
#include <stdlib.h>
```

Makefileはいつものようにこんな感じです。

```makefile:
#
# BSD Makefile for Open Watcom v2
#

WATCOM=/home/hiroki/ow/open-watcom-v2/rel
.export WATCOM

WCL=bwcl
WASM=bwasm

CFLAGS=-I$(WATCOM)/h -I../include -zk0
# Turbo C compatible mode
CFLAGS+=-ecc -zp1

all: sample.exe

sample.exe : sample.c sub.o
        nkf -s sample.c > sample.c_
        $(WCL) $(CFLAGS) -fe=$@ sample.c_ sub.o ../turboc/galib.lib

sub.o: sub.asm
        $(WASM) sub.asm

clean:
        rm -rf *.c_ *.o *.err *.com *.exe
```

出来上がったsample.exeと圧縮ファイルに入ってたgainit.exeをPC-9801に転送して実行してみました。

まずgainit.exeを実行します。デフォルトの解像度だとLCDディスプレー(LCD-A173K)が対応していなくて表示できなかったので/mオプションで表示できる解像度を指定してます。

![IMG_20210319_070239.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/94ef57bb-efc5-d7b7-7c9a-914540476b01.jpeg)

sample.exeを実行します。

![IMG_20210319_070319.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/440aa392-e501-2a38-eeb2-2f57b2272845.jpeg)

GA-1280Aでは1024*768の解像度は4種類の周波数で出力できて、LCDディスプレーが対応していない周波数の場合、アプリケーションが起動すると表示できなくなります。ちょっとややっこしいのが解像度はGAINITでも指定できますが、アプリケーションの方でも指定できたりします。GAINITで指定した解像度をアプリケーションが設定した場合はそのままになりますが、違っていた場合は変更されて、どの周波数になるかは分からないので、表示できなくなる可能性があるようです。

|解像度|カラー|
|:--|:--|
|640*480|モノクロ,4色,16色,256色,65536色|
|800*600|モノクロ,4色,16色,256色,65536色\*|
|1024*768|モノクロ,4色,16色,256色,65536色\*|
|1280*960|モノクロ\*,4色\*,16色\*,256色\*|
|1280*1024|モノクロ\*,4色\*,16色\*,256色\*|

*はGA-1280AのみでGA-1024A非対応

モノクロ,4色,16色,256色は1ピクセル1バイトで65536色は1ピクセル2バイトになります。当時一般的だった256色の表示は1バイトの値がパレットを示して、実際の色はパレットで設定されていました。また65536色はRGBが5,6,5ビットで構成され計16ビットになりハイカラーと呼ばれていました。

githubに上げようかと思ったのですが、転載禁止だったようなので、とりあえず手順だけメモにしてみました。

# マンデルブロを表示してみた

下記のページを参考にマンデルブロを表示してみた。

https://tony-mooori.blogspot.com/2015/10/processing_5.html

```c:
#include <stdio.h>
#include <conio.h>

#include "gagraph.h"

int width, height;

/* Znを何回漸化式で計算するか */
int N = 255;
/* Znの最大値 */
int L = 255;
/* 拡大率 */
float SCALE = 3.0;

/* 漸化式にもとづいてZnが発散するnを計算 */
int calc(float x, float y) {
  float tx, ty;
  float zx = 0.0;
  float zy = 0.0;

  for (int i = 1; i <= N; i++ ) {
    tx = zx;
    ty = zy;

    zx = tx*tx-ty*ty+x;
    zy = 2*tx*ty+y;

    /* 発散した（閾値を超えた）場合はiを返す */
    if ( zx*zx + zy*zy > L )
      return i;
  }
  
  /* 発散しなかった場合は0を返す */
  return 0;
}

void draw() {
  /*中心に原点を持ってくる*/
//  translate(width/2, height/2);
//  background(0);

  for (int a = -width/2; a <= width/2; a++ ) {
    for (int b = -height/2; b <= height/2; b++ ) {
      /* 複素数c=x+yiを定める */
      float x = SCALE * a / width;
      float y = SCALE * b / height;
      /* 漸化式に基づいて計算 */
      int r = calc(x, y);

      /* 収束の速度に応じて色を指定 */
      /* 下のプログラムは適当。stroke(赤成分緑成分,青成分) */
//      stroke(r%256, r*4%256, r*16%256);
      /* 点の描画 */
//      rect(a, b, 1, 1);
      GAsetPixel(a + width/2, b + height/2, r%256);
    }
  }
}

void main()
{
int i;

  if (GAinit(HRESO_65536C)) {
    printf("ERROE\n");
    return;
  }
  GAclrScreen();
  GAcrtSel(CRT_GA);
  width = 1024;
  height = 768;
  draw();
  while(1)
  {
    if (kbhit()) break;
  }
  GAcrtSel(CRT_PC);
}
```

PC-9801FA2(80486SX 16MHz)で表示するのに6時間くらいかかりました。

![IMG_20210319_181109.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/e47e986d-538c-d465-d607-d9a7246fb4f1.jpeg)