Texas Instruments TI-99 / 4aコンピュータは、米国以外ではほとんど知られていませんが、そこで非常に人気がありました(200万台以上の車が生産されました)。 このコンピューターは家庭用として作成されましたが、基本的な機能(多くの点でアーキテクチャを決定し、その後運命を決定しました)は、通常のTTLロジックを使用して組み立てられた既存の本格的なミニコンピューター
TI-990に基づいていることです。 実際、TI99 / 4AコンピュータのTMS9900マイクロプロセッサはTI-990の実装ですが、チップの形をしています。 TI-990は1975年に、TMS9900は1976年に発売されました。
このように、TI99 / 4a(わずかに単純なTI-99 / 4は1979年にリリースされ、すでに1981年にTI-99 / 4aがリリースされました)は、ホームコンピューター用の非常に奇妙なアーキテクチャを継承しました。 まず、TMS9900マイクロプロセッサには16ビットが搭載されており、正直な16ビットのデータバスが搭載されています(これは1970年代後半です!)。 第二に、チップにはレジスタがありません(PC、フラグ、およびWP "レジスタ"ポインタを除く)。 レジスタと呼ばれるものは、サイズが256バイトの16ビットスタティックRAMの別のチップに配置され、メモリおよび(最初の16ワード)レジスタR0..R15として同時にアドレス指定できます。 スクラッチパッドと呼ばれます。
代わりに、ハードウェアスタックはありません。代わりに、このRAM自体のWPレジスタの先頭へのポインターを変更することにより、ルーチンの呼び出し時に値を保存します(Sparcのレジスタウィンドウに似ています)。 祖先(TI-990)では、マルチタスクを実装するときにコンテキストを切り替えるためにも使用されました。
TMS9900のクロック周波数は3 MHzですが、命令はかなりの数のクロックサイクル-少なくとも8を占有します。同時に、乗算と除算も実装されます(124クロックサイクル)。
残念ながら、プロセッサ以外はすべて禁欲的です。 前述の小さなスタティックRAMに加えて、ビデオメモリもあります-ビデオコントローラーを介してアクセスされる16kbの低速8ビットDRAM。
言い換えれば、追加の周辺機器なしで、TI99 / 4Aは256バイトのRAM、組み込みのBASIC ROMおよびカートリッジプログラムを備えた16ビットコンピュータです(8kbまでの正直にアドレス指定されたROMまたはそれ以上のトリック)。
カセットからでも、通常のプログラムを裸のコンピューターにロードすることは不可能です。 このためのRAMはありません(256バイトはカウントされず、残りはビデオメモリです)。
したがって、最低限必要なコンピューター構成はPEB(Peripheral Expansion Box)です。これは、拡張カード、ドライブ、および32kbメモリ拡張用の特別な大きなバスケットです。 またはNanoPEB-上記のすべてを含む最新のデバイス。
PEB / NanoPEBの場合、エディター/アセンブラーカートリッジも必要です(これがないと、BASICでプログラムをダウンロードして実行できるだけでなく、前述の追加の32 KBのRAMが含まれます)。
TMS9918ビデオコントローラー(MSXおよびColecoVisionでも使用)は、グラフィック(256x192、15色)およびテキストモードをサポートし、キャラクタージェネレーターを変更できるようにし、32個のハードウェアスプライト8x8および16x16を同時に表示できます(true、一度に1行に含めることができるのは4つまでです)。
サウンドはTMS9919を介して出力されます(アナログのSN76489はIBM PCjr、BBC Micro、ColecoVision、一部のセガコンソールで使用されていました)。
4チャネル(3つの長方形ジェネレーターと1つのノイズジェネレーター)、16ボリュームレベル。
TMS9900プロセッサ(TMS9985)の8ビットバージョンが当時準備ができていなかったという事実により、ビット深度の点でそのような不均一で、時には厄介なアーキテクチャが得られたと考えられています。
ソフトウェアに関しては、TI99 / 4Aは教育目的を目的としていました(実際、AtariやCommodoreとは対照的です)。 上記のアーキテクチャの奇妙な点と合わせて、これは非常に少ないゲーム(もしあれば)につながりました。 コンピューターが米国だけで配布されていたという事実は、デモシーンの欠如もこれに追加しました(このプラットフォームでは、私の99troイントロは2番目だったようです)。
現在のビジネスの状態
すでに述べたように、カートリッジ(ある場合)から何かを開始できる場合を除き、裸のTI99 / 4aではほとんど何もできません。 通常の操作に必要なPEB拡張バスケットは非常に高価であり、多くのスペースを占有します。 歴史的に、TIでのすべての重大な開発とすべてのアクションはまったく同じPEBに結び付けられていたことが判明したため、マシンの現代のファンはそれをエミュレートする道を歩みました(誰もROMカートリッジのエミュレーターを気にしないようです)。
PEBの最新の代替品は
NanoPEBです。 ある程度の忍耐力があれば、ebayで、または50〜80eの個々の売り手から見つけることができます。
このデバイスは、コンピューターの右側のポート(音声シンセサイザーと同じ場所に挿入します。シンセサイザーを介して挿入することもできます)、32kbの追加RAM、3つのドライブ(コンパクトフラッシュカード上)、RS-232ポートをエミュレートします。
すべてが同じCF7 +デバイスもありますが、RS-232の代わりにパラレルセントロニクスポートがあります。
NanoPEBが存在するだけで、BASIC上のプログラムのみをダウンロードできます(標準のTI BASICからは、完全にダーティで非自明なハッキングを除き、プログラムをマシンコードで実行することはできません)。
したがって、最上部のポートに固定されているエディター/アセンブラー(EA)カートリッジが絶対に必要です。 これにより、通常のプログラムを既にダウンロードして実行できます。 カートリッジはebayでも検索されます。 代わりにカートリッジExtended Basic(XB)を使用できるようです。
プログラムをCompactFlashカードに転送するには、特別なユーティリティを使用する必要があります。 最も人気のあるのはti99dir(Windows用)です。
F18Aプロジェクト-TMS9918AビデオコントローラーをFPGAに実装し、いくつかの機能を追加したものに言及する価値があります。 つまり 通常のTI-99 / 4aのビデオチップは新しいものに交換されますが、古いソフトウェアはすべて以前と同じですが、VGAモニターに画像を表示したり、以前はアクセスできなかったビデオモードを設定したりすることができます。
開発
ここでは説明しませんが、基本プログラムに加えて、プログラムをマシンコードで表すことができる2つの主な形式があります。エディター/アセンブラーを介したディスクからのダウンロードとカートリッジです。
EA経由でダウンロードしたファイルはEA3と呼ばれます(エディター/アセンブラーでは、3番目のメニュー項目「LOAD AND RUN」を選択してダウンロードする必要があるため)。 任意のメモリ領域で起動できます(つまり、EAはロード時にリンクを実行します)。 エミュレータの場合、このようなファイルはディスクイメージ(.DSK)に保存され、Dis / Fix 80という形式になっています。
また、それほど頻繁ではありませんが、EA5と呼ばれるメモリイメージファイルが表示される場合があります(EAでは、5番目のメニュー項目「プログラムファイルの実行」を選択してロードされます)。 これらは既にメモリアドレスに関連付けられたリンクファイルです。 エミュレータは、「プログラム」としてディスクイメージにも保存されます。
確実にコードでプログラムディスクからダウンロードするには、カートリッジエディター/アセンブラー(またはアナログ)が必要です。
カートリッジのプログラムはアドレスに厳密に関連付けられており、ROMにフラッシュされる単なるバイナリです(エミュレータの場合、これは.RPK形式で、あまり一般的ではありません-.BIN)。
アセンブリ言語プログラムを作成するには、大きく異なる2つのアプローチがあります。 1つ目は、いわゆる GPL言語。 これは、パフォーマンスと機能の両方の点で、拡張基本(XB)とアセンブラーのクロスです。 つまり すべての場合、ROMに存在するルーチンは頻繁に使用され、重要なことには、割り込みを有効にする必要があります。
2番目のオプションはアセンブラーで、これについて説明します。
TI-99 / 4Aの主な異常な機能は、実際にはTMS9900プロセッサーにあります。 当時の家庭用コンピューターで使用されていたほとんどのプロセッサーとは、次の点で区別されます。
物理的に、プロセッサには3つのレジスタ(ST(フラグ)、PC(コマンドポインター)、WP(ワークスペースポインター))しかありません。 レジスタR0〜R15は、チップ外部のスタティックRAMにあります。 開始アドレスはWPレジスタに保存されており、変更できます。 通常、> 8300に設定されます(記号 ">"は16進数システム、記号 ":"-バイナリを意味します)。
> 8300から> 83FFまで、「スクラッチパッド」と呼ばれる256バイトの静的16ビットRAMがあります。
これを使用すると、他の動的8ビット(標準拡張32kb)よりも約2倍高速になります。
多くのアドレッシングモードがあり、1つのコマンドで、たとえば、メモリセルから別のセルに値を転送すると同時に値を変更できます。
プロセッサにはスタックがありません。LWPIaddrコマンドを使用して、メモリ領域へのレジスタのマッピングを使用して、コンテキストを保存および復元することになっています。
サブプログラムはBL
ADDRコマンドによって呼び出され、次のアドレスをR11レジスタに挿入します。 したがって、戻るにはB * R11(別名RT)が使用されます。 BLWPもあります。これは、戻りアドレスに加えてワークスペースを保持します(同時に低速です)。
通常、最初に行うことは、すべての割り込みをオフにして、レジスタの先頭をスタティックRAMの先頭に設定することです。 したがって、調達プログラムは次のようになります。
DEF START WRKSP EQU >8300 START LIMI 0 LWPI WRKSP ... * SOME CODE HERE END START
このレジスタアーキテクチャにより、プログラミング機能が表示されます。 すなわち:
1.レジスタには、R1、R2などとしてだけでなく(アドレス空間にあるため)、メモリセルとしてアクセスできます。 これにより、特に、レジスタの下位バイトと上位バイトを個別に操作できます。これは、定数によって事前定義されています。
ws0 equ >8300 ; Workspace 0 ; Register direct low-byte access R0L equ ws0+1 ; Workspace 0 R0 low byte R1L equ ws0+3 ; Workspace 0 R1 low byte R2L equ ws0+5 ; Workspace 0 R2 low byte
ただし、コマンドでレジスタをメモリに単純に置き換えることが常に可能であるとは限らないことは明らかです(このコマンドの場合、目的のアドレス指定モードは単純に不可能な場合があります)。
一方、まだ必要です。なぜなら 半分のレジスタ(MOVB、SWPB、AB、SB、一部のロジック)を操作するコマンドはほとんどありません。
もちろん、現在インストールされているワークスペースに関係なく、(メモリ内の対応するアドレスにある)ワークスペース内のレジスタに常にアクセスできます。
2.スタックがないため(プログラムによってシミュレートされる場合もあります)、ワークスペースを切り替えることでレジスタの保存と復元が行われます。 これを集中的に使用すると、利用可能な256バイトの高速SRAMはすぐに終了します-それらは常に欠落しています。
TMS9900のコードがどのように見えるかを示すための小さな例は、Hello Worldです。
DEF START WRKSP EQU >8300 VDPWD EQU >8C00 * VDP RAM write data VDPWA EQU >8C02 * VDP RAM read/write address START LIMI 0 * disable interrupts LWPI WRKSP * set default workspace * set VDP RAM start address (low and high byte) LI R0,>0000 ORI R0,>4000 SWPB R0 MOVB R0,@VDPWA SWPB R0 MOVB R0,@VDPWA LI R1,HELLOWORLD * ascii string address LI R2,12 * total chars NEXTCHAR MOVB *R1+,@VDPWD * put next char on screen DEC R2 JNE NEXTCHAR LOOPBACK JMP LOOPBACK * stop and do nothing HELLOWORLD TEXT 'HELLO WORLD!' * string data BYTE 0 END START
これは、最新の(かなり伝統的ではない)アセンブラーTMS9900です。 最初は、ラベルの後にコロンがないことに加えて、レジスターはRとして数字ではなく単純な数字として書き込まれました。 つまり 古いアセンブラのLI 4.5とMOV 7.8は、新しいアセンブラのLI R4.5とMOV R7、R8です。
これは読みやすさを増すものではなかったことがわかりやすいので、今ではRを記述しています(ただし、現代のアセンブラーでも古いバージョンのレコードを理解しています)。 ただし、一部の人々は両方の構文に干渉します。 その結果、同じソースコードで、多数のニーモニックSLA R5,0(レジスタR0のビット数だけR5を左にシフト)とSLA R5,1(_one_ビットだけR5を左にシフト)を見つけることができます。
いくつかの(医療:)関心はコマンドXにあります。コマンドXは、コードがパラメーターとして渡される命令を実行します。
; B *R11 LI R9,>045B ; B *R11 X R9 ; LI R1,>1234 LI R0,>0201 ; LI R1,xxx X R0 DATA >1234 ; xxx (>1234)
Xは、タブのナビゲーションだけでなく、デバッグの目的にも使用できると考えられています。 さて、自己修正コードが必要な状況では。
メモリーカード
> 0000 -----------
コンソールROM
> 2000 -----------
低メモリ拡張
> 4000 -----------
周辺カードROM
> 6000 -----------
カートリッジROM / RAM
> 8000 -----------
スクラッチパッドRAMメモリマップデバイス
(> 8300から> 83FFまでは、256バイトの静的RAMがあります。
ほとんどの場合、プロセッサレジスタは8300以上で表示されます。 ビデオ、サウンド、シンセサイザー、GROMにアクセスするためのFrom> 8400 to> 9C02アドレス
> A000 -----------
高メモリ拡張
(標準の32kb RAM拡張。C> A000は通常、ディスクからロードされた典型的なプログラムを開始します)
...
> FFFF
ROMに関しては、TI-99 / 4aはいわゆるGROMを使用します。 これらは完全にプロセッサのアドレス空間にマッピングされるわけではありませんが、データは順次アクセスされます。データの開始アドレスはGROMの特別なアドレスに入力され、そこから別の特別なアドレスからデータが読み込まれます。 この場合、GROMデータの現在のアドレスは、読み取りごとに自動的に増加します。
GROMから文字列を印刷する
li r0, >0874 ; starting GROM address of small character set GROMSC movb r0,@GROMWA ; set GROM read pointer to address 06B0 (high part) nop ; wait a beat (not sure if necessary) movb @WR0LB,@GROMWA ; set GROM read pointer to address 06B0 (low part) li r0,>0000+(8*32*8) ; VDP Pattern Table start address movb @R0L,@vdpwa ; Send low byte of VDP RAM write address ori r0,>4000 ; Set read/write bits 14 and 15 to write (01) movb r0,@vdpwa ; Send high byte of VDP RAM write address li r1,GROMRD li r2,32 nextchar: movb *r1,@vdpwd movb *r1,@vdpwd movb *r1,@vdpwd movb *r1,@vdpwd movb *r1,@vdpwd movb *r1,@vdpwd movb *r1,@vdpwd ; movb *r1,@vdpwd clr @vdpwd ; skip one byte dec r2 jne nextchar
グラフィックス
グラフィックとテキストを表示するために、TDP-99 / 4aにはVDP TMS9918aビデオチップが装備されており、
MSX1および
ColecoVisionでも使用されています。
VDPでは、あまり成功していない15色(背景が透けて見える透明な+1)で256x192の解像度のグラフィックスとモノクロスプライトを表示できます-同じサイズの32個の8x8または16x16の重要な制限:1行に4個以下のスプライト。
VDPは16kb DRAMであり、グラフィックス(テキスト)、色、スプライトに分散されます。
ビデオメモリは、プロセッサのアドレス空間にマップされません。 それに書き込むには、最初に特定のアドレスにアドレスが記録されるビデオメモリの開始アドレスを入力し、次に別のアドレスに必要な値を連続して書き込む必要があります。 この場合、次の各値はビデオメモリのアドレスの1ずつ増加します。
ビデオモードとメモリ割り当てに応じて、アドレス指定の利便性、使用メモリ、および色数(ピクセルブロック内)の観点から最適なモードを選択できます。 基本的に、すべてのモードはテキストです。 すべての場合において、画面上のさまざまな場所に配置でき、変更できる「キャラクター」という概念があります。 ただし、外観がコードと一致するように文字を再プログラムできるため、実際にはモードは既に「グラフィック」になっています。 ただし、これは1980年代の多くのビデオコントローラーの典型です。 比較的最近のVGAでも、このような機会がありました(著者は、色用に個別のメモリを備えた640x400高速モードを実装するためにそれを使用しました)。
ほとんどの場合、TIはグラフィックモードIを使用します(このモードでは、コンピューターの電源を入れて初期化すると表示されます)。 その中で、8x8ブロックごとに2色(背景と画像)を設定できます。 合計ブロック32x24。 このモードの唯一の利点は、色の変化率が比較的高いことです。
また、マルチカラーモード-解像度が64x48のグラフィックモードで、大きなピクセルごとに色が設定されます(ただし、何らかの種類のプラズマまたはANSIアートを描画しない限り、この解像度では)いくつかの純粋なテキストモード40x24文字-カラーとモノクロ。
VDPで最も強力で興味深いモードは、いわゆるグラフィックモードII(別名「ビットマップモード」)です。 このモードでは、8x1ピクセルブロック内で2色(背景と画像)を使用できます。 つまり、水平8ピクセルごとに2色です。 残念ながら、ブロックの順序(ピクセルの順序、色の順序)は、文字出力を除くすべてにとって非常に不便です-バイトは上から下に0-8になり、次に右から次は上から下に8-15になります。 右端に。 その後、すべてが左から右に再び繰り返されます。
モードを設定すると、属性のアドレス(カラーテーブル)、ビットマップ(パターン)、ビットマップのブロックを形成する文字の順序(名前テーブル)、スプライトのデータ(スプライトデータ)、スプライトの属性(スプライト属性)も設定されます。 アドレスを指定することはできません。結果として、16384バイトのすべてのビデオメモリが合理的に使用されるように、いくつかのオプションを選択する必要があります。 たとえば、私のイントロ「99tro」には、次のようにメモリを割り当てました(グラフィックモードII):
> 0000-> 1800パターンテーブル-6144バイト(> 1800)
> 1800-> 2000スプライトパターン-64スプライトx 32バイト= 2048バイト(> 800)
> 2000-> 3800カラーテーブル-6144バイト(> 1800)
> 3800-> 3b00名前テーブル-768バイト(> 300)
> 3b00-> 3b80スプライト属性= 32スプライトx 4バイト= 128バイト(> 80)
スプライトには2つのサイズがあります-8x8または16x16(すべてのスプライトが一度に切り替えられます)に加えて、それらを2回(一度にすべて)引き伸ばすこともできます。
スプライトの総数は、画面32に同時に表示されます(ただし、1行に4つまで表示されます)。 同時に、32個の16x16スプライトを2セット使用するには、スプライトパターン用の2kbのメモリで十分です。
スプライトごとに、次のパラメーターを設定できます(シリーズの各バイトに対して、スプライト属性エリアを使用):
0-垂直座標(-32-191)
1-水平座標(0〜255)。 255-画面の右端の後ろのスプライト。
2-パターンを取得する場所へのポインター(スプライトパターン内)
3-ビット4〜7は色を決定し、ビット0-早期のクロック(スプライトを水平方向に32ピクセル左にシフトします)
失敗した編成と組み合わせたビデオメモリの直接アドレス指定の欠如と、一度に1バイト以上の転送命令がプロセッサにないため、迅速に更新できません。 たとえば、VGM音楽を並行して再生しながら256x8ピクセル領域の水平スムーズスクロールを実装すると、フレーム内でのビームの後方への移動に時間がかかります。 つまり もう時間がありません。
ゲーム(現代)では、この問題はかなりunningな方法で解決されます。スクロールすると、スクロールされた領域全体が更新されず、変更のみが必要になります。 したがって、画面の内容は、これらの変更が最小限になるように考慮されます。 また、一般的に使用されるのは、低い色解像度(8x8ブロックごとに2色)のグラフィックモードIです。
他の多くのシステムと同様に、TI-99 / 4aでは、画像をビームの垂直帰線に合わせることが非常に望ましいです。 これを行うために、VDPは適切な割り込みを生成します-フレームの下部の描画の開始時に。
次のオプションが利用可能です。
1.割り込みを完全に無効にすることができます(LIMI 0 + VDP専用の命令-レジスタ1の対応するビットを設定)。 この場合、すべてが高速になりますが、何らかの方法でリバースビームを追跡することはできません。
2.中断を完全にオンにします(LIMI 2およびVDP)。 その後、何かを行う独自の割り込みハンドラをハングさせることができます。
3. VDPで割り込みを有効にしますが、LIMI 0命令で割り込みを無効にします。この場合、ハンドラーは呼び出されませんが、VDPステータスレジスタのビットをチェックすることで、手動でビームを後方に監視できます(レジスタを読み取った後、このビットは自動的にリセットされます。リセットすると、次の割り込みは生成されません)。
vwait: movb >8802,r12 ; read VDP status register andi r12,>8000 jeq vwait ; Wait for vsync
かなり典型的なスキームは、VDPからの割り込みがオンになり、一般的な割り込みがオフ(LIMI 0)になるときですが、メインループでは短時間(LIMI 2)オンになるため、割り込みに掛かっているハンドラー(音楽の再生など)が制御を取得することがあります。
すべてのエミュレータがこの割り込みを正しく模倣するわけではありません。 しかし、MESSはこれをほぼ適切に実行します。 図では、簡単なテストを見ることができます-フレームの色は、垂直リトレース(実際のTIと2つのエミュレーター-MESSとjs99er)に比べて多少遅れて変化します。
音
1.標準音
音楽や効果音を受信するために、TMS9919チップがTI-99 / 4aにインストールされています(アナログ:SN76489、SN76496)。 3つの独立したトーンジェネレーターと1つのノイズジェネレーターです。 15の音量レベル。
これはかなり人気のあるチップ(一部のコンソール、IBM PCjr / Tandy-1000などで使用)であるため、多くの情報があります。
TI-99 / 4a用のMOD2PSGトラッカーがあります(通常はWin7 64ビットで起動します)。 特に、psgmodファイルをダウンロードして、vgmとepsgmodをエクスポートできます。
TursiによるEPSGMOD Player(epsgmod形式のデータが必要で、VDPを中断するためにハンドラーをハングアップする)の2つの動作するプレーヤーがあります。
次のように接続されます。
def start start: lwpi >8320 li r0,musicdata bl @SGPLAY again: limi 2 limi 0 ; .... your code (vsync etc..) ... b @again musicdata: bcopy "music.epsgmod" copy "test_music_playervbr.a99" copy "test_music_player.a99" end start
プレーヤーのこの接続では、ソースからREFとENDを削除する必要があります(従来のアセンブラーで使用するためのものです)。
メインループでは、割り込みが一時的にアクティブになることに注意してください(limi 2)。 これは、プレーヤーが動作するために必要です。これは、リバースビームからVDPを中断することで動作します(1/60秒ごとに発生します)。 この場合、プレーヤーのSGTICKサブルーチンが呼び出されます。
したがって、NTSCバージョンのコンピューターと音楽もNTSCであることが重要です(フレームレートが一致する必要があります)。
(同じ作者の)2番目のプレーヤーはVGM形式のファイルを再生します(VGM圧縮用のVGMCompユーティリティも含まれています)。 このハンドラーはハングアップしません。60Hzの周波数で手動で呼び出す必要があります。
次のようになります。
def start vdpsta equ >8802 ; VDP RAM status start: limi 0 lwpi ws0 ; player expects our workspace to be >8300 clr r2 li r1,musicdata bl @stinit again: clr r12 ; set CRU base (doesn't need to be in loop, but provides delay) tb 2 ; check VDP interrupt input (Tests a CRU bit) jeq loop ; if not set, skip calling music movb @vdpsta,r12 ; read status register, which in turn clears the interrupt bit bl @stplay ; call play function - it returns with the wrong workspace * check for song end movb @songwp+14,r3 jne notdone clr r2 ; play again li r1,musicdata bl @stinit notdone: lwpi >8300 ; so restore the right one ; .... your code (vsync etc..) ... b @again musicdata: bcopy "music.vgm" copy "tiplayer.a99" end start
私の意見では、プレーヤーの2番目のバージョンは品質が高く(特定の音楽に依存する場合があります)、ハンドラー(本当に必要な場合は自分でハングアップできます)よりも手動呼び出しの方が柔軟性があります-割り込みを有効にする必要はありません。
彼には30Hzプレーヤーのオプションもあります。 同時に、60 Hzの周波数で呼び出す必要がありますが、2番目の呼び出しごとに使用されます。 したがって、プロセッサの負荷は軽減されますが、音楽の音質は低下する可能性があります(使用されるエフェクトによって異なります)。
どうやら、プレーヤーに(またはVGMにエクスポートするときに)バグがあるため、音楽のループに不可解な問題が発生します。
2.音声シンセサイザー
音声シンセサイザーはTI-99 / 4aの非常に人気のある周辺機器であるため、かなりの数のプログラムがそれを使用しています。 シンセサイザーはコンピューターの右側のポートに接続します(NanoPEBがある場合は、シンセサイザーに直接接続できます)。 内部には、ワードのデータを含むROM、LPCデコーダー(TMS5220)、およびDACがあります。
2つの動作モードがあります。 最初に、コンピュータはシンセサイザにROMのどの単語を発音させるかを指示します(単語はほとんどありません)。 2番目(Speak-External)では、直接圧縮されたLPCデータを転送することができ、シンセサイザーはそれを単純に再現します。 データのパッケージ化には、WinXPで実行される古代のQBox Proプログラムが使用され
ます (プロセスは
ここに示されてい
ます )。
シンセサイザーは、アセンブラープログラムから直接制御できます。 ただ遊びたいだけなら、たとえば音声エディタなどのカートリッジが必要です(入力したテキストを発音できるようにし、標準のBasicで単語を再生するコマンドも追加します)。 ターミナルエミュレーターカートリッジを使用すると、個々の音素を発音し、それらを任意の単語に結合できます。
最も有名なエミュレーターでは、シンセサイザーがサポートされています。 最高のサポート(ハードウェアが完全にエミュレートされる)はMESS / MAMEで実装されると考えられています。
以下は、シンセサイザーのROMからLPCデータを取得する「HELLO」という単語を発音する例です。 ドキュメントでは、コードが8ビットバスのRAMで実行された場合(つまり、コードが16ビットスクラッチパッド上にあることが必要)、ステータスチェックは不可能であると示されていますが、エミュレーターと実際のコンピューターをチェックした後、これは再保険であると考えられます(おそらくまた、VDPの場合、これらの要件はすべて、鉄の非常に初期のバージョンに関連しています。 結果は次のような短いコードです。
; speaks 'HELLO' from speech synth ROM def start SPCHRD equ >9000 ; addr to read from synth SPCHWT equ >9400 ; addr to write to synth (>10 - read, >4x - Load-Address, >50 - speak, >60 = speak-ext ) H50 BYTE >50 ; speak command start: limi 0 ; loading speech address (5 nibbles of data required) using >4x Load-Address command ; >4x >4x >4x >4x >40 (end marker >0) li r0,>351a ; address of 'HELLO' in synth ROM li r2,4 ; 4 nibbles loadlp: src r0,4 ; start with least significant nibble mov r0,r1 src r1,4 andi r1,>0f00 ; get only particular nibble ori r1,>4000 ; put in >4x00 format movb r1,@SPCHWT ; write nibble dec r2 jne loadlp li r1,>4000 movb r1,@SPCHWT ; write fifth nibble (end marker) movb @H50,@SPCHWT ; execute speak command loopback: b @loopback end start
ROMからのすべての単語のアドレスは、ブックEditor Assembler Manualに記載されています。
QBox Proを使用してLPCに変換された任意の音声を再生する場合、最も単純な場合、コードは次のようになります。
def SPEAK SPEAK li r2,1750 ; number of speech BYTEs to poke (see end of QBox data) li r3,speech ; speech data address limi 0 ; no interrupts loop movb *r3+,@>9400 ; poke a BYTE of speech data dec r2 jeq quit ; repeat until end of data jmp loop ; else go 'round again quit limi 2 ; interrupts allowed rt speech ; 10 Voiced 4 Unvoiced 8 kHz 5220 ; [Coded LPC] ; .... *.sfm QBox Pro ; nb bytes: [1750] end
QBox Proでは、音声付きのwavファイルを準備する必要があります。 明確な男性のスピーチが最適です。 1つのフレーズが約1キロバイトを占めます。
歌や楽譜を渡すことはできません。 LPCでコーディングした後、そのような音は完全に認識できなくなります。
QBox Proの設定と操作:
byte 8khz 5220 Project/Add files select file Process/Medium bit rate /OK Edit/Concatenations Insert/Concatenation/Concat Name/ "TEST" Insert/Phrase/OK Format/LPC 10V, 4UV /OK Project/Exit/Save
結果:test.sfm
交差手段
PCでプログラムを開発およびテストし、TI-99 / 4aにダウンロードするには、次のものが必要です。
鉄:
-PC / Win7(64ビットが良い)
-TI-99 / 4a
-カートリッジエディター/アセンブラー(またはマシンコードでプログラムをダウンロードして実行できるもの)
-NanoPEBまたはCF7 +(ドライブをエミュレートし、CompactFlashカードからTI-99 / 4aにプログラムをロードするため)
ソフト:
-多くのTI-99 / 4aエミュレーターの1つはMESS / MAMEまたはjs99er(またはそれ以上)です。
-ファイルとディスクイメージを操作するためのアセンブラとユーティリティを含むxdt99パッケージ(特に、NanoPEBに必要な形式でディスクイメージをCompactFlashカードに書き込むためのxvm99)
プロセスの構成:
カートリッジ用のプログラムとディスクからロードするためのプログラム-さまざまなもの。 フォーマット(RPKおよびDSK)だけでなく、メモリの操作に関しても(2番目のオプションは32kbのメモリ拡張を一時停止します)。 最終的に実際のマシンでコードを実行するという目標がある場合は、ディスクバージョンに集中する必要があります。 検討します。
エミュレータは互いに大きく異なるため、最高の名前を付けることは非常に困難です。 これは、エミュレーションの品質の問題だけでなく、完成したプログラムを起動することの利便性/単純さの問題でもあります。
最も有名なもの:mess(mame)、js99er、v9t9、classic99。
それらはすべて完璧ではありません。 エミュレータと実際のハードウェアとの速度に10%の差があることを期待することはかなり可能です(具体的には、messとjs99erがすべてのコードを実際のTIより少し速く実行することを確認しました。
xdt99をアセンブラとして使用する場合、プロセスは次のようになります。
xas99.py -R --jumpstart %1.a99 ( )
-Rオプションを使用すると、ソーステキスト内のレジスタに適切な名前を付けることができます(r0、r1、...)。 従来のアセンブラTMS9900では、コマンド内のレジスタは単純に数字で書かれているため、混乱が生じます。
xdm99.py work.dsk -a %1.obj -n %1-O -f DIS/FIX80 ( )
オブジェクトファイルは、内部に16進コードを含むテキストファイルであることに注意してください。 それでも、これは最終的なバイナリファイルではありませんが、TI-99 / 4aにプログラムをダウンロードする特性(エディター/アセンブラー経由)により、多くの場合、既製のプログラムと見なされます。 さらに、通常、起動時にメモリの特定の領域に関連付けられていません。
最終的なバイナリが必要な場合は、xas99に-iオプションを追加します。次に、ポイント3からではなく、エディター/アセンブラーのポイント5からロードする必要があります。 -iの代わりに、別々の部分に分割せずに8kを超える最終バイナリファイルが必要な場合は、-bを使用する必要があります。また、-Lオプションを指定すると、.lstリストファイルを取得できます。自動ロード用の特別なカートリッジイメージにより、作業が多少簡素化されます(xdt99ドキュメントの「ジャンプスタート」を参照)。このイメージを使用すると、エミュレーターでエディター/アセンブラーを使用せずにボタンを押してファイル名を入力できます。カートリッジを選択すると、完成したコードがディスクから自動的にロードされます。たとえば、この場合のmess(mame)は次のように始まります。 mame64.exe ti99_4a -peb:slot8 tifdc -peb:slot2 speech -flop1 %1.dsk -cart jumpstart.rpk -window -ui_active -skip_gameinfo
デバッガが必要な場合は、-debug(オプションが指定されている場合はエミュレータからデバッガに入る-` キーで)を追加することもできます。パラメータ" ti99_4a "は、コンピュータのNTSCバージョン(最も一般的な)を置き換えます。 PALバージョンの場合、これはti99_4aeになります。少なくともフレームレートが異なるため、この違いは非常に重要です。最初の場合、人員60Hz、2番目の50Hz。誤った選択は、たとえば、音楽の再生速度を低下させる可能性があります(NTSCで作成され、PALが選択されている場合)。開発中のアプリケーションのサイズがかなり大きい場合、または何か時間がかかる場合は、-speed 20オプションを使用してエミュレーションを高速化できますプログラムレコードをNanoPEB形式でCompactFlashに転送するには、xvm99.pyを使用できます \\.\PHYSICALDRIVE2 1 -w work.dsk
コンピューターのPHYSICALDRIVE2が、CFが挿入されているデバイスに正確に対応していることを確認してください(そうしないと、ディスク上のデータが損なわれる可能性があります!)。Windowsでは、次のコマンドで表示できます wmic diskdrive list brief /format:list
複数のドライブをエミュレートするために1つのCFに複数のイメージが存在する可能性があるため、2番目のパラメーターはドライブに対応します。1)のDSK1。暫定的に、FAT16でCFをフォーマットすることをお勧めします。その後、TI BasicでTIPEに「呼び出しフォーマット(1)」を入力し、TI BasicからNanoPEBを挿入する必要があります。フラッシュドライブのコンテンツを表示します。 xvm99.py \\.\PHYSICALDRIVE2 1 -i
TI自体にプログラムをロードする場合、エディター/アセンブラーおよびNanoPEBでカートリッジを挿入する必要があります。NanoPEB、次にコンピューターの電源を入れます。メニューで、オプション "2"-"Editor / Assembler"を選択し、項目3(または5)でDSK1.FILENAMEと入力してEnterキーを押します。ファイル名の大文字小文字は重要です。付録1-イントロ99TRO
TI-99 / 4aを研究する過程で、「99tro」 (ソース)を書きました。これは、Revision'2016で発表されたChaos Constructions'2016での小さな招待イントロです。ソースコードに加えて(コードは非常にひどい-そのように書かないでください!)ここでいくつかの説明をします。主なアイデアは、可能であれば、イントロがCommodore 64の古いcracktroのスタイルを伝え、TI-99 / 4aビデオおよびオーディオチップのより控えめな機能に合わせて自然に調整することです。大ざっぱに言えば、私はカラーロゴ、スムーズにスクロールするテキスト行、虹色のストライプ、スプライトからぶら下がっている碑文のようなものが欲しかった。すぐに、コンピューターの次の重要な制限と欠点が明らかになりました。-ハードウェアスクロールはありません。ビデオメモリをシフトおよび書き換えすることによってのみ実行できます- ビデオメモリとの交換(これはスプライトとグラフィックスおよびテキストにも適用されます)は非常に遅く、プロセッサの比較的高い周波数は保存されません(交換のため16ビットも同様) VDPを使用すると、8ビットバス上に移動します)。-VDPには、文書化されていない、または音声で文書化されていないバグが多数あります(これは驚くことではありませんが、TMS9918は最初の特殊なビデオチップの1つです)。数回、これにより、すでにほぼ完成した部分を放棄しなければならなかったという事実に至りました。-スプライトの非常に制限された機能-1行につき4つのみ(自動的に画面上のスプライトで何もできないことを意味します)、1色、スプライトの色または座標の簡単な変更のための多数のプロセッサ命令。-音楽(vgm)の再生には、かなりのプロセッサ時間がかかります。 Tursiのプレーヤーのソースコードで述べられているように、これは特定の音楽によって異なりますが、30Hzバージョンでは2〜20%です。私の特定のケースでは、少なくとも10〜15%が得られました。-トラブルは便利なデバッガーにあります(実際、同じ状況はVectrexエミュレーターにありました-どちらの場合にも強力なデバッガーがありますが、実際には、それらの使用はスピードアップよりもスローダウンする可能性が高いため)-コードを迅速にチェックできない本物の鉄。これを行うには、すべてをオフにし、USBフラッシュドライブを削除し、PCに挿入し、コードをコピーして、PCから削除し、TIに貼り付け、ディスクエミュレーターとTI自体をオンにし、エディター/アセンブラーを選択し、プログラムロードポイントを選択して、DSK1.program_nameと入力し、Enterキーを押しますダウンロードを待ちます(約1分)。その結果、次第にアイアンの実装を許可されたもののみが以前のアイデアから残りました(もちろん、これがこのプラットフォームとこのプロセッサの最初のプログラムであることを考慮に入れて):-CHAOS CONSTRUCTIONS'2016ロボットの頭の碑文/ロゴ-音楽のビートに合わせて点滅ロボットの目と口-文字ごとに表示され、脈動するカーソルをたどり、数行のテキストを表示します- テキスト行をスムーズにスクロールします-バックグラウンドミュージック(vgm)何らかの形でTI-99 / 4aの強みを使用するために、最大グラフィックのモードを選択しましたと色の解像度-グラフィックモードII(ビットマップ)。ゲームでは、非常にまれにしか使用されません。 16kbのビデオメモリをすべて必要とするため、画像の更新に関して非常に遅いです。ただし、ゲームとは異なり、私の場合、トリック(一般的にデモとイントロの特徴)を使用することができました。他の場所では色を動的に更新しませんでした。花に関連するすべてのものは、メインサイクル以外の最初に一度だけ確立されました。サイクルでは、ビットマップのみが変更され、2つのスプライトが切り替わりました。上部のロゴは、最初にPhotoshopで描画され、Convert9918ユーティリティを使用してVDPのビデオメモリダンプに変換され、次にこれら2つのステップが周期的に繰り返されました。変換後(かなり湾曲した15色と色解像度2色、8水平ピクセル)に、可能な限り適切に見えるように、元の画像に改良が加えられました。このような場合によく発生する、再生された複合NTSC信号の歪み特性は手元で言う必要があります-CRTモニターでは、エミュレーターよりも画像の方が明らかに良く見えます(さらに暖かくてランプが多くなります)。私は、プラットフォームの成功にとって、その(プラットフォーム)開発者の16色の正しい選択がいかに重要であるかを真剣に認識しました。 TI-99 / 4aの場合、これらの色は非常にうまくいきません(さらに、15個あります)。さらに、NTSCビデオ信号のカラーコーディングの問題に初めて対処する必要がありました。写真は、単一ピクセルの色がどのように変わるかを示しています(PALでは、これも問題を引き起こしますが、比較にならないほど小さいです)。下部の滑らかなスクロールは、1つの同様の例(Matthew Hagerty)から取られ、変更されました。正直に言うと。このように短い期間、TMS9900アセンブラーをそこまで使用したテクニックを繰り返すほど深く浸透させることはほとんどできませんでした。これなしでは、すべての作業の全体的なパフォーマンスが十分ではありませんでした。スクロールでは、文字の部分が非常に巧妙に左にシフトされ、結果がVRAMにコピーされます。合計で、高さ8ピクセルの領域がスクロールします。上で述べたように、操作はビットマップに対してのみ実行されます。白と青のストリップの形をした色付きの背景が事前に描画され、スクロールの影響を受けません。スクロールはメインサイクルで最も高価な操作であるため、すべてがスクロールおよび音楽からさらに押し出されます(逆方向のビームに収まるのをやめると、音楽の速度が低下し始めます)。残念ながら、実際には、まだ少し遅くなります。コードをデバッグした両方のエミュレーターは、実際の鉄よりも少し速く動作しました。何が問題なのかは明確ではありません。カーソルの後ろのテキストは、画面の中央に書き込まれます。これを美しく実装する方法はたくさんありましたが、ビデオメモリが遅く、VDPのバグがあるため、最終的には全員を放棄しなければなりませんでした。その結果、ループの反復ごとに1文字が描画されます(つまり、8バイトのビデオメモリが更新されます)。可能な8行すべてのテキストについて、青とグレーのシェード間をスムーズに移行するように背景が事前に設定されています。脈動カーソルは、画像が4つのメモリ位置から周期的に取得されるスプライトです。サイズの異なる正方形の4つのフレームが判明します。ロボットの目と口の点滅については、16x16スプライトの3つのフレームに実装されています(これもパフォーマンスを向上させることを目的としています)。特定のフレームは、サウンドチップのチャネルの1つのボリュームに応じて選択されます(このデータはプレーヤーによって返されます)。スプライトとフォントは、マゼランプログラムで編集されました。コードはプロセッサレジスタに3つの異なるワークスペースを使用します-プレーヤー用に1つ(そしてワークスペースだけでなくスクラッチパッドも必要です-貴重な16ビットRAM、その部分を移動してコード実行の速度を上げることができなかったため)、 2番目はスクロール用で、3番目は他のすべてのもの(ループ内のカウンター、カーソル座標など)その結果、イントロの合計サイズは約22kbでした。もちろん、主要部分は非圧縮グラフィックス(12kb)とRLE圧縮音楽(1.8kb)です。したがって、コード自体は6〜7 kbの領域を使用します(それでも、デバッグのみに使用されたフラグメントがあります)。付録2-イントロスピーチトロ
Speechtro (ソース)と呼ばれる1キロバイトのイントロは、99troのすぐ後に書かれ、DIHALT'2016(1kbのローエンドイントロで1位を獲得)で発表されました。コアには2つのアイデアがありました。1.音声シンセサイザーを使用して何かを行うには(TI-99 / 4aの所有者の間では非常に一般的であり、エミュレーター-MESS / MAMEおよびjs99erでもサポートされています)。2.ラスター効果を模倣して、多数の色を視覚化してみてください。少しためらった後、両方のアイデアを1つの作品にまとめることにしました。音声は、シンセサイザーROMにフラッシュされた単語を使用します(1 kbの直接LPC圧縮の場合、あまり多くの音声が収まらないため)。 ROMにはそれらが非常に少ないため、使用可能な単語から適切なトピックに関する首尾一貫したスピーチを作成するのにかなり時間がかかりました。残念ながら、シンセサイザ辞書の一時停止は提供されていません。一時停止として、かなりランダムなアドレスを使用しました。このデータは「ゴロゴロ」と聞こえます。これは、第一に、コードを保存して簡素化し、第二に、単なる沈黙よりも面白いように聞こえます。画像に関しては、最初にラスター効果(光線が目的の線に沿った瞬間に背景色を変更する)を実装したいと考えました。技術的に不可能であることが判明しました(上のスクリーンショットでは、実際のTIおよびエミュレーター-MESSおよびjs99erでこれを行う試みを見ることができます)、別のオプションが選択されました-属性メモリーの操作によりラスター効果をシミュレートします。グラフィックモード2では、各8x1ブロックは独立した背景色と画像色を持つことができるため、1ピクセルの高さの各バーは背景とテキストに異なる色を持つことができます。 15色しかなく(ストライプで10色しか使用されていない)にもかかわらず、さらに多くの色があるようです。別の困難がテキストの結論をもたらしました。TI-99 / 4aの設計上の特徴は、ROM(いわゆるGROM)がプロセッサのアドレス空間にマッピングされないことです。したがって、フォント出力のデータは、GROMから順番に(バイトごと)抽出されます-開始アドレスを設定し、同じメモリ位置を読み取ります。選択された「スモールキャップ」セットには、文字A〜Z(数字なし)のみが含まれているため、簡単にわかります。星は、斜めに忍び寄るバグのように、8x8のスプライトで実装されています。2つの正方形の定規で単語を発音するプロセスでは、(条件付きで)現在の単語のアドレスの一部がシンセサイザーのROMに表示されます。TI-99 / 4aのリソースリンク
ここでは、さまざまなレトロなプラットフォームの下で私の作品を見ることができます。また、GitHub でそれらのソースを見ることができます。この機会を利用して、8月末に毎年サンクトペテルブルクで開催されるChaos Constructionsフェスティバルに興味のあるすべての人を招待したいと思います。PS鉄片、Kirill TimofeevとTimur Tashpulatovに感謝します