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

このメモでは、ジョイスティックの読み取り、スプライトの位置の変更、水平方向の反転、Sega Genesis エミュレータ、および場合によってはコンソール自体のプロセスについて説明します。

将棋ジョイスティックのクリックの読み取りと「イベント」の処理は、次のスキームに従って行われます。

<オル>

  • 押されたボタンのビットの組み合わせをリクエストする
  • 押されたボタンのビットを読み取る
  • ゲームロジックレベルでの処理
  • スケルトン スプライトを移動するには、現在の位置の変数を保存する必要があります。

    RAM

    ゲーム ロジック変数は RAM に保存されます。これより優れたものはまだ見つかっていません。変数アドレスを宣言して、レンダリング コードを変更しましょう。

    skeletonYpos = $FF0002 
    frameCounter = $FF0004 
    skeletonHorizontalFlip = $FF0006
    
        move.w #$0100,skeletonXpos 
        move.w #$0100,skeletonYpos 
        move.w #$0001,skeletonHorizontalFlip 
    
    FillSpriteTable: 
        move.l #$70000003,vdp_control_port 
        move.w skeletonYpos,vdp_data_port  
        move.w #$0F00,vdp_data_port 
        move.w skeletonHorizontalFlip,vdp_data_port 
        move.w skeletonXpos,vdp_data_port 
    

    ご覧のとおり、作業に利用できるアドレスは 0xFF0000 で始まり 0xFFFFFF で終わり、合計 64 KB のメモリが利用可能です。スケルトンの位置は、skeletonXpos、skeletonYpos で宣言され、水平方向の反転は、skeletonhorizo​​ntalflip で宣言されます。

    ジョイパッド

    VDP と同様に、ジョイパッドの操作は 2 つのポートを介して個別に行われます。制御ポートとデータ ポート。最初のポートは 0xA10009 と 0xA10003 の共通番号です。ジョイパッドを使用する場合、興味深い機能が 1 つあります。まず、ポーリング用のボタンの組み合わせをリクエストする必要があります。次に、バス上の更新を待った後、必要なボタンの押し方を読み取ります。 C/B および D パッド ボタンの場合、これは 0x40 です。以下の例:

      move.b #$40,joypad_one_control_port; C/B/Dpad 
      nop ; bus sync 
      nop ; bus sync 
      move.b joypad_one_data_port,d2 
      rts 
    

    レジスタ d2 では、ボタンが押されたか押されなかったかの状態が残ります。一般に、日付ポートを通じて要求された内容が残ります。その後、お気に入りのエミュレータの Motorola 68000 レジスタ ビューアに移動し、キーストロークに応じて d2 レジスタが何に等しいかを確認します。賢明な方法では、マニュアルでそれを知ることができますが、私たちは彼らの言葉を鵜呑みにしません。 d2

    レジスタで押されたボタンのさらなる処理

        cmp #$FFFFFF7B,d2; handle left 
        beq MoveLeft  
        cmp #$FFFFFF77,d2; handle right  
        beq MoveRight  
        cmp #$FFFFFF7E,d2; handle up  
        beq MoveUp  
        cmp #$FFFFFF7D,d2; handle down  
        beq MoveDown  
        rts

    Проверять нужно конечно отдельные биты, а не целыми словами, но пока и так сойдет. Теперь осталось самое простое – написать обработчики всех событий перемещения по 4-м направлениям. Для этого меняем переменные в RAM, и запускаем процедуру перерисовки.

    Пример для перемещения влево + изменение горизонтального флипа:

        move.w skeletonXpos,d0 
        sub.w #1,d0 
        move.w d0,skeletonXpos 
        move.w #$0801,skeletonHorizontalFlip 
        jmp FillSpriteTable

    После добавления всех обработчиков и сборки, вы увидите как скелет перемещается и поворачивается по экрану, но слишком быстро, быстрее самого ежа Соника.

    Не так быстро!

    Чтобы замедлить скорость игрового цикла, существуют несколько техник, я выбрал самую простую и не затрагивающую работу с внешними портами – подсчет цифры через регистр пока она не станет равна нулю.

    Пример замедляющего цикла и игрового цикла:

      move.w #512,frameCounter 
    WaitFrame: 
      move.w frameCounter,d0 
      sub.w #1,d0 
      move.w d0,frameCounter 
      dbra d0,WaitFrame 
    GameLoop: 
      jsr ReadJoypad 
      jsr HandleJoypad 
      jmp GameLoop 
    

    この後、スケルトンの実行速度が遅くなりますが、これは必要なことです。私が知っているように、「速度を落とす」ための最も一般的なオプションは、垂直同期フラグをカウントすることです。これにより、画面が描画された回数をカウントできるため、特定の fps に関連付けられます。

    リンク

    https://gitlab .com/demensdeum/segagenesisamples/-/blob/main/8Joypad/vasm/main.asm

    ソース

    https://www.chibiakumas.com/68000/platform2.php
    https://huguesjohnson.com/programming/genesis/tiles-sprites/

    Leave a Comment

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