1

6502 マイクロ コントローラー命令セットを使用して、20Hz の方形波と 30Hz の方形波のアセンブリで 2 つの出力を生成しようとしています。これまでのところ、20Hz 波で出力できます。

%uasm65,title="SQUARES"
    org 0200h
    lda #1d
    sta 0a200h
Main:
    ;jump to the subroutine Delay and do it
    jsr Delay
    lda 0a200h
    inc Count1
    lda Count1
    cmp #3d
    beq Reset1
    jmp Main

Reset1:
    lda #0d
    sta Count1
    lda 0a200h
    eor #00000001b
    sta 0a200h
    jmp Main

Reset2:
    jmp Main

Delay:
    ;Save registers on the stack.
    pha
    txa
    pha
    tya
    pha

;Change the number that is being loaded into the
; 'A' register in order to change the delay time.
    lda #01h

OutLoop:
    ldx #04h

InLoop1:
    ldy #0ffh

InLoop2:
    dey
    bne InLoop2

    dex
    bne InLoop1

    sec
    sbc #1d
    bne OutLoop

;Restore registers from the stack.
    pla
    tay
    pla
    tax
    pla

    rts

Count1:
    dbt 0d

Count2:
    dbt 0d

    end

%/uasm65

私の理解では、これを達成するためにできることは、60Hz の方形波を使用して 30Hz と 20Hz を取得することです。ポートの他のビットの状態に影響を与えずに、PortA のビット 5 に 20Hz の方形波を出力し、PortA のビット 6 に 30Hz の方形波を出力するにはどうすればよいでしょうか? つまり、ここで 60 から 20 と 30 を取得するにはどうすればよいでしょうか。カウントに 7 をチェックさせ、カウント 2 をインクリメントしますか? どんな助けでも大歓迎です。

4

2 に答える 2

3

各ピンに 1 つずつ、2 つの個別のカウンターが必要です。

Main:
    ;jump to the subroutine Delay and do it
    jsr Delay
    lda 0a200h      ; ?? what's this doing here?

    inc Count1   ; count1 is for the 20 Hz bit pin
    lda Count1
    cmp #3d       ; 60/20 = 3, so counter1 will have to reach 3
    bne Skip1     ; otherwise skip toggling
toggle_pin5:
    lda #0d       ; reload first Counter
    sta Count1
    lda 0a200h
    eor #00000001b
    sta 0a200h
skip1:

    inc Count2    ; count2 is for the 30 Hz bit pin
    lda Count2
    cmp #2d       ; 60/30 = 2, so counter2 will have to reach 2
    bne Skip2     ; you could also "bne Main" here
toggle_pin6:
    lda #0d       ; reload 2nd Counter
    sta Count2
    lda 0a200h
    eor #00000010b ; you will want to change this for the correct value to "set bit6 of PortA"
    sta 0a200h

skip2:
    jmp Main    

Reset1:     ; not needed anymore
Reset2:     ; not needed anymore

Delay: [ ... ]

ループ内で、Reset1 (または Reset2) に分岐し、Main に戻ることはあまりお勧めできません。2 番目のピンの 2 番目のチェックをスキップします。(私が行ったように) いくつかの命令に分岐するか、JSR/RET を使用することをお勧めします。

    cmp #3d
    bne SkipCall    ; counter value NOT reached, so skip "Reset"
    jsr Reset
SkipCall:
    <...>

Reset: 
    lda #0d
    sta Count1
    <...>
    ret
于 2016-03-24T13:13:38.127 に答える
2

命令セットを読んだところによると、これは機能し、Tommylee のコードよりも短いはずです。(私はそれを出発点として使用しました)。

結果がゼロに達したときにゼロフラグを設定するデクリメントを使用する場合、asm ではゼロに向かってカウントすることが望ましいです。その後、個別の比較は必要ありません。これにより、コードサイズを0x1Dバイトまで減らすことができます (私の 2 番目のバージョンの場合)。

decメモリオペランドを使用しても、結果に応じてフラグが設定されると想定しています。ウィキペディア以外の 6502 ドキュメントは見ていません。:P 質問のコードはdey/bneを使用しているので、それが正しいと仮定し、フラグを設定します。

より少ない命令で最適化する方がよいと仮定すると、遅延ループを大幅に削減するように努める必要があります。たぶんbne、ループ条件としてメモリデクリメントのネストされたループだけです(つまり、2 ^ n回ループします)?メモリを使用するとより多くの電力がかかる場合を除きますか?

Main:
    ldx  #3d         ; 60/20 = 3: toggle every 3 iterations
    ; stx  Count5    ; Count5 is for the 20 Hz bit wave on pin5
    ldy  #2d         ; 60/30 = 2: toggle every 2 iteration
    ; sty  Count6    ; Count6 is for the 30 Hz bit wave on pin6
    ; omit the stores: Count5 and Count6 are already initialized.

    ; lda  0a200h      ; start with the initial state of the I/O port
    lda  #1d          ; constant initial state

squarewave_loop:
    jsr  Delay
    ; lda  0a200h     ; or do this here, so Delay doesn't have to save/restore A

    dec  Count1    
    bne  skip1        ; toggle when it reaches zero
toggle_pin5:
    stx  Count5       ; reload first countdown counter
    eor  #00000001b
skip1:

    dec  Count2
    bne  skip2        ; toggle when it reaches zero
toggle_pin6:
    sty  Count6
    eor  #00000010b ; FIXME: which bit maps to bit6 of Port A?
skip2:

    sta  0a200h       ; always store, even if there was no state change
    jmp squarewave_loop

Delay: [ ... ]

Count1:
    dbt 3d
Count2:
    dbt 2d

または、count1/count2 に / をdey使用しますdex

次に、カウンターを格納するためのメモリは必要ありません。また、メモリ オペランドを含む命令のエンコーディングはより長いと仮定します。

Main:
    ldx  #3d         ; 60/20 = 3: toggle every 3 iterations
    ldy  #2d         ; 60/30 = 2: toggle every 2 iteration

    ; lda  0a200h      ; start with the initial state of the I/O port
    lda  #1d          ; constant initial state

squarewave_loop:
    jsr  Delay
    ; lda  0a200h     ; or do this here, so Delay doesn't have to save/restore A

    dex
    bne  skip1
       ;toggle_pin5:     ; runs when 1st down-counter hits zero
    ldx  #3d             ; reload the countdown
    eor  #00000001b
skip1:

    dey
    bne  skip2
       ;toggle_pin6:     ; runs when 2nd down-counter hits zero
    ldy  #2d
    eor  #00000010b ; FIXME: which bit maps to bit6 of Port A?
skip2:

    sta  0a200h          ; always store, even if there was no state change
    jmp squarewave_loop

Delay: [ ... ]

コメントを取り除き、ラベルの末尾から文字を削除すると、これはhttp://www.masswerk.at/6502/assemblyr.htmlで組み立てられます。:遅延ループを除いた合計サイズは、コードの 0x1D バイトです。

于 2016-03-25T05:20:15.187 に答える