-

差分

移動先: 案内検索

LIBRARIES PUBLIC DOCUMENT BANKING LIBRARY

21,148 バイト追加, 2017年9月19日 (火) 21:02
ページの作成:「==始めに== Hitech-C Banking Library for Hitech-C CはHI-TECH Cコンパイラのためのライブラリです。MSX-DOS2に対応するメモリセグメントの割...」
==始めに==

Hitech-C Banking Library for Hitech-C CはHI-TECH Cコンパイラのためのライブラリです。MSX-DOS2に対応するメモリセグメントの割り当て機能をアクティブにして、メモリの制約のない大容量のDOS2用のプログラムを作成するための環境を提供しています。
ライブラリには、基本的なバンキングのほか、割り込み、スロット、キー入力、グラフィックスなどのための関数が含まれます。

===開発環境===

<strong>OS:</strong> Windows XP以上

<strong>CP/M エミュレーター:</strong> CP/M EXEcutor (http://hp.vector.co.jp/authors/VA000084/)

<strong>C Compiler / Assembler:</strong> HI-TECH C v3.09 (CP/M用公開ツール)

<strong>MAKE Tool:</strong> GNU Make Windows用 v3.81 (http://www.gnu.org/software/make/)

<strong>バンキングライブラリとバンク構築ツール:</strong>本プログラム

そのほか、ソースのプロジェクト管理/ビルド用のIDEを使用すると便利です。
私はopen source IDEであるCode::Blocksを使用しています。

Cは、元のCP / M用のツールとしてのサブディレクトリをサポートしていません。
ここではCP/M EXEcutorのディレクトリtoドライブマッピング機能を利用して構築をしています。

もし、Windowsではなく、Linuxのような他のOSで開発環境を作成するには、該当するOS用のCP/Mエミュレータで、このようなディレクトリのマッピング機能が必要です。

ちなみに、私が提供するバンク構築ツールはすべてCP/M用の実行ファイルで作られています。

===実行環境===

メインラム256KB以上のMSX2とMSX-DOS2が必要です。

バンクされるサイズは32KBですので、最小プログラムである1バンクのプログラム製作時、DOS2の基本TPAメモリのほか32KBが追加で必要になります。 (DOS2システム32KB + TPA 64KB + 1バンク32KB =合計128KB)

ちなみにMSXturboRは64KBを内蔵BIOSのシャドウ領域として使用するので、A1STモデルでは、空きメモリがあまり多くありません。 (バンク3つ分が可能= 96KB)

===メモリマップ===

0000H~00FFH :
DOSシステムコール

0100H~7FFFH :
プログラム領域バンク#0 <-> プログラム領域バンク#0....

8000H~83FFH :
バンキングおよび割り込みルーチン

8400H~8FFFH :
バンキングスタック

9000H~FFFFH :
内部バッファ、
共有ヒープ、スタック、
およびMSXワークエリア



バンク#0には、プログラムローダが入るので、ユーザーコードはバンク#1から書かれます。バンク#0の残る領域にコードを追加することもできます。

main()関数とISR(interrupt service routine)は、バンク位置に制限を受けないので、どこに置かれてもかまいません。 LIBリンクは、各バンクごとに別々に行われます。

たとえばバンク#1はLIBMSX2.LIBを、バンク#2はLIBFMSX2.LIBを、などと異なるリンクをすることができます。


;以下は注意事項です。


各バンクのプログラムは、TEXT、DATA、BSSすべて合わせ32KBを超えることはできません。
バンク内でmallocなどの動的メモリの割り当て時に8000Hをオーバーしないように注意する必要があります。

バンクのデータ伝達は、共有ヒープ(bl_malloc系関数を使用)で可能であり、バンク関数呼び出しは、ビルド時にバンキングhelperルーチンを介して自動的に行われるので、コーディング時、別に考慮する事項はありません。

==ビルド==

====開発ツールのインストール====

GNU Makeは、Windowsのpathが通ったところへコピーします。
参考までに、Windowsのコマンドウィンドウを開いてpath [Enter]と打ってみると、pathが通ったディレクトリを確認することができます。


<strong>MinGW</strong>などのgcc系ツールがインストールされている場合は、既存のインストールされたMAKEが使われます。

CPMエミュレータ、バンクビルドツール、HI-TECH Cなどの他のパッケージは、すべて一つのディレクトリに集めておきます。参考までに、圧縮ファイルのCPMEMU_HI-TECH Cディレクトリにあらかじめコピーしておきました。

以下は、私が使用しているC:\Emul\CPMEMU_HI-TECH_Cディレクトリの様子です。

{|
|+
|<strong>C:\Emul\CPMEMU_HI-TECH_C</strong>
|-
|BLCRT.C||CPM.EXE||MSXBIOS.H||LIBG.LIB
|-
|BLGRPFNT.C||ASSERT.H||MSXIO.H||CRT.O
|-
|BLGRPINI.C||BANKCALL.H||SETJMP.H||CRT2.O
|-
|BLSRC.CFG||BLGRP.H||SIGNAL.H
|-
|BLCALLER.COM||BLGRPDAT.H||STAT.H
|-
|BLEXTREF.COM||BLSTDLIB.H||STDARG.H
|-
|BLMERGE.COM||BLTYPE.H||STDDEF.H
|-
|BLMKRULE.COM||CONIO.H||STDIO.H
|-
|CGEN.COM||CPM.H||STDLIB.H
|-
|CPP.COM||CPM_ORG.H||STRING.H
|-
|CREF.COM||CPUMODE.H||SYS.H
|-
|DEBUG.COM||CTYPE.H||TIME.H
|-
|GEN80.COM||EXEC.H||LIBC.LIB
|-
|LIBR.COM||FLOAT.H||LIBCGEN.LIB
|-
|LINK.COM||GLIB.H||LIBCMSX.LIB
|-
|OBJTOHEX.COM||HITECH.H||LIBCMSX2.LIB
|-
|OPTIM.COM||KEYIO.H||LIBF.LIB
|-
|P1.COM||LIMITS.H||LIBFGEN.LIB
|-
|POPCOM.COM||MATH.H||LIBFMSX.LIB
|-
|ZAS.COM||MSXBDOS.H||LIBFMSX2.LIB
|}

===Hello MSX!===

バンキングプログラムの例であるHELLOプログラムを構築する方法です。
以下はHELLOプログラムのディレクトリのファイルです。
簡単なコードなので、新しいプログラム製作時、デフォルトのテンプレートで使用しても良いです。

{|
|+
|<strong>D:\My_Work\[MSX]\BANKED_APP\HELLO</strong>
|-
|MAKEFILE
|-
|_BUILD.BAT
|-
|MAIN.X
|-
|HELLO.CFG
|}

====Makefile設定====

MAKEFILEは、すべてのバンクのプログラムで共通に使用されるMAKEFILEです。
ユーザーによる修正が必要な部分は、以下の通りです。
2.1の開発ツールをインストールした、ディレクトリのパスを4行目のCPMDIR変数に設定します。

HELLO\MAKEFILE

###
# HI-TECH C package path
#
CPMDIR := C:\Emul\CPMEMU_HI-TECH_C


====CFG設定====

MAKEFILEは共通のMAKE設定なので、ビルドされるプログラムの設定が別に必要です。
この時、使われるファイルが* .CFGです。
CFGファイルは、MAKEFILE内でincludeされて使用されます。

HELLO.CFGのように、ファイル名がプログラムの名前となり、ビルドしたときに実行ファイルの名前を決定します。

以下はHELLO.CFGファイルの内容です。

target := $(CFG)

cflag += \


src-bank00 += \


lib-bank00 += \
A:LIBCMSX2.LIB \


src-bank01 += \
MAIN.C \


lib-bank01 += \
A:LIBCMSX2.LIB \


targetは設定を変更する必要はありません。

cflagは、Cコンパイル時共通に使用されるオプションを追加することができます。
ちなみに、デフォルトのオプションは、MAKEFILEのcflagに入っています。


src-bankXXとlib-bankXXは、各バンクに入る、ソースファイルとライブラリファイルのリストです。
HELLOプログラムでは、MAIN.Cのコードだけ追加がされています。

上記のリストからbank00とbank01二つが見えますが、bank00はバンクファイル(* .OVLファイル)ローダーが基本的に入り、MAIN.Cはbank01に含まれることを知ることができます。

各lib-bankXXは、基本的にLIBCMSX2.LIBをリンクしています。もし浮動小数点ライブラリを使用するときは、LIBFMSX2.LIBをリンクします。


<strong>以下は注意事項です。</strong>

それぞれのソースコードは、コンパイラやアセンブラを経てOBJファイルを生成します。その後LINKを介して各バンクのバイナリコードを生成することになりますが、この時、ソースファイルの数が多い場合、ファイル名が長すぎる場合には、CP/M駆動時のパラメータの長さが超過し、正常に実行ができない場合が発生します。

もし5つ以上のファイルを一つのバンクに入れるときは、ファイル名をできるだけ短くしてください。
例:EX.C、E1.C、E2.Cなど



====main()====

HELLOプログラムのmain()関数は、MAIN.Cファイルに含まれています。
シンプルに"Hello MSX!"を出力してDOS2に戻ってくる簡単なコードです。

/***********************************************************

HELLO (Banking Library Demo)

***********************************************************/

#include <stdio.h>
#include <string.h>
#include <sys.h>
#include <msxio.h>
#include <msxbdos.h>
#include <bltype.h>
#include <blstdlib.h>

int main(int argc, char* argv[])
{
printf("Hello MSX!\n");

return 0;
}

;


コードを見ると、一般的なCコードとの違いはありません。
ただし、以下#includeは、バンキングアプリケーションの使用時に必須で入れます。

#include<bltype.h>
#include<blstdlib.h>

====_BUILD.BAT====

最終的に、コマンドウィンドウでビルドをするときに使用されるバッチファイルです。
ビルド後の出力メッセージは、_BUILD.TXTファイルとして保存されます。
ビルドエラーが発生した場合、このファイルをご覧いただくになります。
以下はHELLOプログラムのビルド/クリーン時の例です。
ビルド:_BUILD HELLO
クリーン:_BUILD HELLO CLEAN

====生成ファイル====

ビルドをするようになれば、プログラム名(CFGファイル名と同じ、ここHELLO)のディレクトリが生じ、実行ファイル(*.COM)とバンクファイル(*.OVL)の二つが生成されます。
以下はHELLOプログラムをビルドしたときのソースとOUTPUTディレクトリの様子です。
HELLOプログラムのバンクファイル(HELLO.OVL)は、1つのバンクを使用するので、32KBのサイズです。

{|
|+
|<strong>D:\My_Work\[MSX]\_BANKED_APP\HELLO</strong>
|-
|HELLO
|-
|MAKEFILE
|-
|B00.AS
|-
|B01.AS
|-
|HELLO.B01
|-
|_BUILD.BAT
|-
|MAIN.C
|-
|HELLO.CFG
|-
|B00.LST
|-
|B01.LST
|-
|B00.MAP
|-
|B01.MAP
|-
|HELLO.MK
|-
|B00.O
|-
|B01.O
|-
|BLCRT.OBJ
|-
|MAIN.OBJ
|-
|EXTERN.REF
|-
|_BUILD.TXT
|}

{|
|+
|<strong>D:\My_Work\[MSX]\_BANKED_APP\HELLO\HELLO</strong>
|-
|HELLO.COM
|-
|HELLO.OVL
|}

以下はMSXエミュレータで直接実行してみた様子です。


A:\>HELLO
Hello MSX!
Volume in drive A: has no name
Directory of A:\

HELLO COM 7552 11-03-26 2:00a
HELLO OVL 32768 11-03-26 2:00a

39K in 2 files 40K free
A:\>


==シンボルリスト==

===BLTYPE.H===

バンキングライブラリ関数を使用する際に必要なデータ型の宣言が入っています

;int8_t, int16_t, int32_t,
;uint_8_t, uint16_t, uint32_t


===BLSTDLIB.H===

バンキングアプリケーションで使用される基本的な変数と関数です。

====バンク番号====

;extern int16_t bl_bank

参照する場合は、現在のコードが実行されているバンク番号を知ることができます。 (値を変更しないでください。) バンク番号はCFGファイルに設定された番号と一致します。

====TSR====
;void bl_tsr_on(void)

TSRの機能をオンにします。 TSRはプログラムが終了したとしても、バンクコード(* .OVL)は、メモリに常駐するようにします。そのプログラムの再実行時、常駐されたバンクコードをそのまま実行するためDATA、BSS 領域は初期化されません。

既存の実行中のプログラムの状態を維持する場合、プログラムサイズが大きい場合、または高頻繁で使用されている場合(DOSシェルなど)に使用すると、ディスクの再読み込みをしないので便利です。

====共有ヒープ====

共有ヒープメモリ管理関数です。共有ヒープは9400H以降の領域に割り当てられます。

;void *bl_calloc(size_t num, size_t size)
calloc()に対応する関数です。

;void bl_free(void *ptr)
free()に対応する関数です。

;void *bl_malloc(size_t size)
malloc()に対応する関数です。

;void *bl_realloc(void *ptr, size_t size)
realloc()に対応する関数です。

====割り込み====

MSX-DOS2環境では基本的にすべてのPAGEはRAMに選択されます。 0038Hアドレスの割り込みベクタ処理はPAGE3のworkareaで行われ、既存のMSX BIOSのISR処理のためにPAGE0がMAIN BIOSスロットに切り替わります。
この時、ユーザーISRコールバックは、直接実行が不可能ですが(PAGE0,1にあるので)、PAGE2に存在するバンキングライブラリのメインISRから各ISRのバンク切り替えを処理するためのメモリの制限がなくなります。
したがってISRは、通常の関数と同じように作成します。

;void bl_enable_bios_timi(void)

MAIN BIOSのISRであるTIMI内部ルーチンを使用しenableにします。 stdioのキー入力とジョイスティック、MUSICなどを使用するときは、オンである必要があります。ちなみにBIOSのTIMIは、基本的にONの状態です。

;void bl_disable_bios_timi(void)

MAIN BIOSのISRであるTIMI内部ルーチンを使用しdisableにします。ゲームなどのキー入力処理を別々に実装したり、割り込み動作速度を高めるためにTIMI内部ルーチンが必要ない場合は、disableにします。 TIMIを切ってもバンキングライブラリでは、VDPのH_BLANK、V_BLANK、SPRITE衝突などの基本割り込み処理を提供します。

;int16_t bl_request_irq(uint8_t irq, uint16_t handler)
IRQを要求し、その割り込みのISRを登録します。 MSXはZ80割り込みベクタモードを使わずに、0038Hの固定割り込みモードを使用します。 IRQ_EXT0からIRQ_EXT7まで外部割込み用ISR 8つを登録することができ、 VDP割り込みはHBLK、VBLK、SPRT 3種類の別のISRを登録することができます。

ちなみにHBLK ISRはVDPのすべてのH_BLANKで実行されるのではなく、VDPのライン割り込みレジスター(R19)に設定されたラインのH_BLANKで実行されます。

;int16_t bl_free_irq(uint8_t irq)

その割り込みのISRを削除します。

;void bl_enable_irq(uint8_t irq)

そのIRQをenableにします。

;void bl_disable_irq(uint8_t irq)
そのIRQをdisableにします。

====フレームレートコントロール====

;void bl_set_frame_rate(uint8_t rate)

V_BLANK wait関数bl_wait_frame_rate()の頻度(rate)を設定します。 V sync 60Hzモードで使用する場合、毎秒60 / rate回に設定されます。

;void bl_wait_frame_rate(void)
bl_set_frame_rate()関数で設定されたVDPのV_BLANK rateになるまで待機します。ゲームやアニメのループなど一定速度で処理が必要な場合に使用することができます。ちなみに、この関数はコールされた瞬間からV_BLANKをカウントするのではなく、バンキングライブラリ内のメインISRでカウントされているV_BLANKが参照されます。

====スロット====

PAGE1(4000H~7FFFH)のスロットを切り替えて、メモリブロック転送をしたり、特定のスロットのアドレスを読み書きすることができます。

;uint8_t bl_read_slot(uint8_t slot, uint8_t *addr)

特定スロットのアドレスに対応されるメモリをreadします。slot番号は、BIOSのRDSLTで使用される形式と同じです。(BIT7:拡張スロットの選択、BIT3,2:拡張スロット番号、BIT1,0:基本スロット番号)

;void bl_write_slot(uint8_t slot, uint8_t *addr, uint8_t data)

特定スロットのアドレスに対応するメモリをwriteします。

;void bl_copy_to_slot(uint8_t slot, uint8_t *dest, uint8_t *src, uint16_t count)

PAGE1のスロットを切り替えて、メモリ転送をします。

;void bl_copy_from_slot(uint8_t slot, uint8_t *src, uint8_t *dest, uint16_t count)

PAGE1のスロットを転換して、メモリ転送をします。 ちなみにbl_copy_to_slot()関数とは、パラメータの順序が違うだけで、動作は同じです。

;void bl_select_page1_slot(uint8_t slot)

PAGE1のスロット?を転換して、割り込みをdisableします。

;void bl_restore_page1_slot(void)

PAGE1のスロットを元のプログラムメモリスロットに回復して、割り込みをenableします。

====16KBのROMイメージの実行====

;void bl_execute_rom(uint16_t addr)

16KBロムイメージを実行します。ロムイメージは、そのアドレスから16KBが転送されてPAGE1にロードされます。その後PAGE0をMAIN BIOSスロットに切り替え、ロムイメージのINITルーチンにジャンプします。 MSX1用128KBitsロムゲームを実行するのに使うことができます。

==デモプログラム==

===HELLO===

2.ビルドの項目で登場したプログラムです。 1つの追加のバンクを使用する簡単なmain()関数で構成されています。

===デモ===

本バンキングライブラリのメインデモプログラムです。
DOS2の基本ディスク管理関数とバンクと割り込みなどの処理を示す例です。

;MAIN.C
テキストメニュー形式になっており、それぞれのサブ関数は、異なるバンクに位置しています。 プログラマは、各関数がバンクメモリ(32KB)を超えない範囲内で自由にコーディングがが可能であり、関数呼び出しも特別の設定が行われることを見ることができます??

;DOS.C

DOS2の環境変数の使用と、特定のファイル名を検索し、ファイルサイズを示す例です。


;INTR.C
簡単に外部割り込みとV_BLANK割り込みを使用する例です。MAIN BIOSのキー処理ルーチンと一緒に動作する様子を見ることができます。


;INTR_TR.C
turboRでの高速割り込み処理を示す例です。1フレーム(1/60秒)にVDPのH_BLANK割り込みを16回使用しています。 ADJUSTレジスタを高速設定して、画面を左右に振るような効果を示しています。ちなみにこの時、ISRは約825μsec(0.000825秒)間隔で実行されています。

;KEYIO.C
キー入力処理を示すデモです。

;GRAPIC.C
公開グラフィックライブラリであるGLIBを使用する例を示します ちなみにGLIBはnativeコードで実装されたものではなくMSX BIOSの内部ルーチンを呼び出す方法です。

;GRP_FONT.C
インターレーススクリーン7のグラフィックスモード(512x424)で8x16英語フォントと16x16ハングルのフォントを出力する例です。 完成形ハングルを組合せ型に描画するコードも含まれており、フォントがHI-TECH Cのインラインアセンブラを使用して迅速に描かれます。

;EXEROM.C
コナミの16KBロムゲームであるKing's valleyのロムイメージをプログラムの中で直接実行する例です。

===MPXPS===

キム・ジュンソンさんのMPXカートリッジを利用してMP3再生するプログラムです。turboRでは、CPUを3.58MHz Z80モードに切り替えるためのコードが入っており、PAGE1のスロット切り替え、MPXカートリッジを見つけるコード、MPXのメモリマップI/Oを処理するサンプルコードを参考にすることができます。

MPXカートリッジにデータを転送する関数では、bl_select_page1_slot()とmemcpy()を使用する方法と、bl_copy_to_slot()を使用する2つの方法を見ることができます。

==謝辞==

警告: 私が作ったバンキングライブラリとビルドツールは、100%の動作保証をしません。 使用時に発生する結果については責任を負いかねますので、ユーザーは利点を注意してください。

意見: 使用中のお問い合わせ、提案、要求などは、電子メール(sharksym@hitel.net)に送ってください。 ちなみに私のブログ(http://sharksym.egloos.com/)も情報を得ることができます。

感謝の言葉: すべての「MSXの天国」グループメンバーの皆さんとバンキングライブラリをテストし応援してくださる方に多くの感謝を申し上げます。

==履歴==

2011.3.26
割り込みとVDPルーチン補完PDFマニュアルを追加。

2010.10.09 ビルドツールの解析バグを修正。

2010.08.06 1次バージョンリリース。

案内メニュー