Sega Genesis #3 のアセンブリでの書き込み

この記事では、アセンブラを使用して Sega Genesis エミュレータでタイルから画像を表示する方法を説明します。
Exodus エミュレータのDemens Deum スプラッシュ画像は次のようになります:

タイルを使用して PNG 画像を出力するプロセスは、段階的に実行されます。

<オル>

  • 画像を将棋画面サイズに縮小する
  • PNG を色とタイルに分けたアセンブリ データ コードに変換します
  • カラー パレットを CRAM にロードする
  • タイル/パターンを VRAM にロードする
  • VRAM のプレーン A/B アドレスにタイル インデックスをロードする
  • Blender などのお気に入りのグラフィック エディタを使用して、画像を将棋画面のサイズに縮小できます。
  • PNG 変換

    画像を変換するには、ImaGenesis ツールを使用できます。wine で作業するには、Visual Basic 6 ライブラリが必要です。これらのライブラリは、 winetricks (winetricks vb6run) を使用してインストールするか、インターネットから RICHTX32.OCX をダウンロードして配置できます。正しく動作するためにアプリケーション フォルダーを参照してください。

    ImaGenesis では、4 ビット カラーを選択し、カラーとタイルを 2 つのアセンブラ形式ファイルにエクスポートする必要があります。次に、色を含むファイルで、各色を単語 (2 バイト) に入れる必要があります。これには、dc.w オペコードを使用します。

    CRAM スプラッシュ画面の例:

      dc.w $0000 
      dc.w $0000 
      dc.w $0222 
      dc.w $000A 
      dc.w $0226 
      dc.w $000C 
      dc.w $0220 
      dc.w $08AA 
      dc.w $0446 
      dc.w $0EEE 
      dc.w $0244 
      dc.w $0668 
      dc.w $0688 
      dc.w $08AC 
      dc.w $0200 
      dc.w $0000 
    

    タイル ファイルはそのままにしておきます。このファイルには、読み込むための正しい形式がすでに含まれています。タイル ファイルの一部の例:

    	dc.l	$11111111	; Tile #0 
    	dc.l	$11111111 
    	dc.l	$11111111 
    	dc.l	$11111111 
    	dc.l	$11111111 
    	dc.l	$11111111 
    	dc.l	$11111111 
    	dc.l	$11111111 
    	dc.l	$11111111	; Tile #1 
    	dc.l	$11111111 
    	dc.l	$11111111 
    	dc.l	$11111111 
    	dc.l	$11111111 
    	dc.l	$11111111 
    	dc.l	$11111111 
    	dc.l	$11111111 
    

    上の例からわかるように、タイルは CRAM カラー パレット インデックスで構成される 8×8 グリッドです。

    CRAM の色

    CRAM へのロードは、制御ポート (vdp 制御) への特定の CRAM アドレスへのカラー ロード コマンドを設定することによって行われます。コマンドの形式は Sega Genesis ソフトウェア マニュアル (1989 年) に説明されています。次の色に移動するには、アドレスに 0x20000 を追加するだけであることを付け加えておきます。

    次に、カラーをデータ ポート (vdp データ) にロードする必要があります。読み込みを理解する最も簡単な方法は、以下の例を使用することです。

        lea Colors,a0 ; pointer to Colors label 
        move.l #15,d7; colors counter 
    VDPCRAMFillLoopStep: 
        move.l  d0,vdp_control_port ;  
        move.w  (a0)+,d1; 
        move.w  d1,(vdp_data_port); 
        add.l #$20000,d0 ; increment CRAM address 
        dbra d7,VDPCRAMFillLoopStep 
    

    VRAM 内のタイル

    次は、タイル/パターンを VRAM ビデオ メモリにロードします。これを行うには、VRAM 内のアドレス (たとえば、0x00000000) を選択します。 CRAM と同様に、VRAM に書き込むコマンドと開始アドレスを使用して VDP 制御ポートに接続します。

    この後、ロングワードを VRAM にアップロードできます。VRAM 自動インクリメント モードがあるため、CRAM とは異なり、各ロングワードにアドレスを指定する必要がありません。 VDP レジスタ フラグ 0x0F (dc.b $02) を使用して有効にできます。

      lea Tiles,a0 
      move.l #$40200000,vdp_control_port; write to VRAM command 
      move.w #6136,d0 ; (767 tiles * 8 rows) counter 
    TilesVRAMLoop: 
      move.l (a0)+,vdp_data_port; 
      dbra d0,TilesVRAMLoop 
    

    プレーン A/B のタイル インデックス

    次に、インデックスに従って画面をタイルで埋める必要があります。これを行うには、VDP レジスタ (0x02、0x04) に入力されるプレーン A/B アドレスで VRAM が埋められます。難しいアドレス指定の詳細については、Sega のマニュアルを参照してください。この例では、VRAM アドレスは 0xC000 です。そこにインデックスをアップロードしましょう。

    いずれにせよ、画像はオフスクリーン VRAM スペースを埋めるため、スクリーンスペースを描画した後、レンダラーは描画を停止し、カーソルが新しい行に移動したときに再び続行する必要があります。これを実装する方法には多くのオプションがあります。私は、画像幅カウンタとカーソル位置カウンタの 2 つのレジスタをカウントする最も単純なバージョンを使用しました。

    コード例:

      move.w #0,d0     ; column index 
      move.w #1,d1     ; tile index 
      move.l #$40000003,(vdp_control_port) ; initial drawing location 
      move.l #2500,d7     ; how many tiles to draw (entire screen ~2500) 
    
    imageWidth = 31 
    screenWidth = 64 
    
    FillBackgroundStep: 
      cmp.w	#imageWidth,d0 
      ble.w	FillBackgroundStepFill 
    FillBackgroundStep2: 
      cmp.w	#imageWidth,d0 
      bgt.w	FillBackgroundStepSkip 
    FillBackgroundStep3: 
      add #1,d0 
      cmp.w	#screenWidth,d0 
      bge.w	FillBackgroundStepNewRow 
    FillBackgroundStep4: 
      dbra d7,FillBackgroundStep    ; loop to next tile 
    
    Stuck: 
      nop 
      jmp Stuck 
    
    FillBackgroundStepNewRow: 
      move.w #0,d0 
      jmp FillBackgroundStep4 
    FillBackgroundStepFill: 
      move.w d1,(vdp_data_port)    ; copy the pattern to VPD 
      add #1,d1 
      jmp FillBackgroundStep2 
    FillBackgroundStepSkip: 
      move.w #0,(vdp_data_port)    ; copy the pattern to VPD 
      jmp FillBackgroundStep3 
    

    この後は、vasm を使用して rom を組み立て、シミュレーターを起動して画像を確認するだけです。

    デバッグ

    すべてがすぐにうまくいくわけではないため、次の Exodus エミュレータ ツールをお勧めします。

    <オル>

  • M68k プロセッサ デバッガ
  • m68k プロセッサ サイクル数の変更 (デバッガのスローモーション モードの場合)
  • ビューア CRAM、VRAM、プレーン A/B
  • m68k のドキュメントと使用されているオペコードを注意深く読んでください (すべてが一見したほど明白であるわけではありません)
  • Github でゲーム コード/逆アセンブリのサンプルを表示する
  • プロセッサ例外のサブルーチンを実装して処理する
  • プロセッサ例外サブルーチンへのポインタは、ROM ヘッダーに配置されます。GitHub には、genesis-debugger と呼ばれる、Sega 用の対話型ランタイム デバッガーを備えたプロジェクトもあります。

    利用可能なツールをすべて使用し、昔ながらの優れたコーディングを行い、Blast Processing を使用することもできます。

    リンク

    https://gitlab.com/demensdeum /segagenesisamples/-/tree/main/6Image/vasm
    http://devster.monkeeh.com/sega/imagenesis/
    https://github.com/flamewing/genesis-debugger

    ソース

    https://www.chibiakumas.com/68000/helloworld .php#レッスンH5
    https://huguesjohnson.com/programming/genesis/tiles-sprites/

     

    Leave a Comment

    Your email address will not be published. Required fields are marked *