ファミコン


数字をカウントするだけ。プログラムの雛形にと思ってメモ。わけもわからず書いている部分が減ってきてよい感じです。

;;; 秒数をカウントして表示

        .inesprg 1              ; プログラムバンク数
        .ineschr 1              ; CHR データバンク数
        .inesmir 0              ; 水平ミラーリング
        .inesmap 0              ; マッパー

;;; =======================
;;;  割り込みハンドラバンク
;;; =======================
        .bank   1
        .org    $FFFA           ; $FFFA から開始

        .dw     main            ; VBlank 割り込み
        .dw     start           ; リセット割り込み
        .dw     0               ; ハードウェア/ソフトウェア割り込み


;;; =======================
;;;  CHR データバンク
;;; =======================
        .bank   2

        ;; sprite
        .org    $0000
        ; .incbin "sprite.chr"

        ;; BG
        .org    $1000
        ;; http://hp.vector.co.jp/authors/VA042397/nes/sample.html
        .incbin "character.chr"


;;; =======================
;;;  プログラムバンク
;;; =======================
        .bank   0

;;; 定数
FPS:    .equ    60              ; frame / second
DIGITS: .equ    6               ; 表示桁数
POS1:   .equ    $20             ; 表示位置 higher byte
POS2:   .equ    $7c             ; 表示位置 lower byte

;;; 変数
FRAME:  .equ    $00             ; frame % FPS
SECONDS:  .equ  $01             ; ここから DIGITS bytes は秒数の各桁 (十進)


        .org    $8000

;;; -----------------------
;;; 初期化

start:
        ;; PPU レジスタ初期化
        lda     #%00010000      ; 初期化中は VBlank 割り込み禁止
        sta     $2000

        ;; VBlank 待ち
.waitVBlank:
        lda     $2002
        bpl     .waitVBlank     ; VBlankが発生して $2002 の7ビット目が1になるまで待機

        ;; PPU レジスタ初期化
        lda     #%00000110      ; 初期化中はスプライトとBGを表示OFF
        sta     $2001

        ;; パレットロード
        lda     #$3f
        sta     $2006
        lda     #$00
        sta     $2006
        ldx     #0
.loadPalette:
        lda     palette, x
        sta     $2007
        inx
        cpx     #$04
        bne     .loadPalette

        ;; ゼロページクリア
        ldx     #0
        lda     #0
.clearZeropage
        sta     <SECONDS, x
        inx
        cpx     #$ff
        bne     .clearZeropage

        jsr     drawCount
        
        ;; PPU レジスタセット
        lda     #%00011110      ; スプライトとBGの表示をONにする
        sta     $2001
        lda     #%10010000      ; 割り込み許可
        sta     $2000

.loop:
        jmp     .loop

palette:
        .byte   $0f, $00, $10, $20
        

;;; -----------------------
;;; メイン

main:
        jsr     increment
        rti


;;; -----------------------
;;; サブルーチン

;;; カウンタをひとつ進める
;;; 必要ならば再描画する
increment:
        ;; FRAME をインクリメント
        inc     <FRAME
        lda     <FRAME
        cmp     #FPS
        bne     .return

        ;; 秒数を繰上げ
        lda     #0
        sta     <FRAME
        ldx     #0
.incrementSeconds
        inc     <SECONDS, x
        lda     <SECONDS, x
        cmp     #10
        bne     .draw           ; 繰上げ終わり

        lda     #0
        sta     <SECONDS, x
        inx
        cpx     #DIGITS
        bne     .incrementSeconds ; 規定桁数以下なら引き続き繰り上げ

.draw
        jsr     drawCount

.return
        rts


;;; カウンタを描画
drawCount:
        ldy     #POS2           ; 表示位置下位byte. digit ごとに decrement
        ldx     #0
.digit
        ;; 表示位置設定
        lda     #POS1
        sta     $2006
        tya
        sta     $2006
        dey
        ;; 数字描画
        lda     <SECONDS, x
        clc
        adc     #$30            ; '0'
        sta     $2007

        inx
        cpx     #DIGITS
        bne     .digit

        ;;  スクロール設定
        lda     #$00
        sta     $2005
        sta     $2005

        rts