Programowanie: Dzielenie 16-bitowe z wynikiem 32-bitowym: Różnice pomiędzy wersjami

Z Atariki
Przejdź do nawigacji Przejdź do wyszukiwania
fmt
w sumie po co dwa razy odejmowanie ...
 
(Nie pokazano 4 pośrednich wersji utworzonych przez tego samego użytkownika)
Linia 9: Linia 9:
         beq ?e
         beq ?e


; <-- czesc pomijalna
         lda fr0    ;dzielnik wiekszy od dzielnej
         lda fr0    ;dzielnik wiekszy od dzielnej
         cmp fr1    ;daje w wyniku zero, a dzielna
         cmp fr1    ;daje w wyniku zero, a dzielna
Linia 15: Linia 16:
         bcs ?div
         bcs ?div


         ldx #$01
         lda fr0
?d      lda fr0,x
         sta fr0+2
         sta fr0+2,x
         lda fr0+1
         dex
         sta fr0+3
         bpl ?d
         lda #$00
         lda #$00
         sta fr0
         sta fr0
         sta fr0+1
         sta fr0+1
         rts
         rts
; -->


?div    lda #$00    ;kasujemy reszte
?div    lda #$00    ;kasujemy reszte
Linia 36: Linia 37:
         rol fr0+3
         rol fr0+3


        sec
         lda fr0+2
         lda fr0+2
         cmp fr1
         sbc fr1
        tay
         lda fr0+3
         lda fr0+3
         sbc fr1+1
         sbc fr1+1
         bcc ?s
         bcc ?s


         lda fr0+2
         sty fr0+2
        sbc fr1
        sta fr0+2
        lda fr0+3
        sbc fr1+1
         sta fr0+3
         sta fr0+3


Linia 65: Linia 64:


Główna pętla zajmuje - w zależności od składników - od 624 do 1152 cykli maszynowych.
Główna pętla zajmuje - w zależności od składników - od 624 do 1152 cykli maszynowych.
== 65C816 ==
<pre>
int16div
        .aw
        .ib
        rep #$20    ;CPU musi byc w trybie natywnym
        sep #$10
        lda fr1    ;dzielnik musi byc wiekszy od zera
        beq ?e
; <-- czesc pomijalna
        lda fr0    ;dzielnik wiekszy od dzielnej
        cmp fr1    ;daje w wyniku zero, a dzielna
        bcs ?div    ;stanowi reszte
        lda fr0
        sta fr0+2
        stz fr0
        rts
; -->
?div    stz fr0+2  ;kasujemy reszte
        ldx #16
?l      asl fr0
        rol fr0+2
        sec
        lda fr0+2
        sbc fr1
        bcc ?s
        sta fr0+2
        inc fr0
        bne ?s
?e      sec
        rts
?s      dex
        bne ?l
        clc
        rts
</pre>
Elegancka procedura biblioteczna powinna jeszcze przechowywać na stosie i przed powrotem do miejsca wywołania przywracać rozmiar rejestrów. W powyższym przykładzie pominięto to, żeby nie zaciemniać zagadnienia.


== Uwagi ==
== Uwagi ==

Aktualna wersja z 23 wrz 2012, 23:35

Procedura dzieli 16-bitową liczbę bez znaku umieszczoną we FR0 ($D4) przez takąż liczbę umieszczoną w FR1 ($E0). 16-bitowy wynik całkowity umieszczany jest w FR0, a 16-bitowa reszta z dzielenia w FR0+2. Opuszczenie procedury z ustawionym znacznikiem C sygnalizuje przepełnienie.

6502

int16div
        lda fr1     ;dzielnik musi byc wiekszy od zera
        ora fr1+1
        beq ?e

; <-- czesc pomijalna
        lda fr0     ;dzielnik wiekszy od dzielnej
        cmp fr1     ;daje w wyniku zero, a dzielna
        lda fr0+1   ;stanowi reszte
        sbc fr1+1
        bcs ?div

        lda fr0
        sta fr0+2
        lda fr0+1
        sta fr0+3
        lda #$00
        sta fr0
        sta fr0+1
        rts
; -->

?div    lda #$00    ;kasujemy reszte
        sta fr0+2
        sta fr0+3

        ldx #16

?l      asl fr0
        rol fr0+1
        rol fr0+2
        rol fr0+3

        sec
        lda fr0+2
        sbc fr1
        tay
        lda fr0+3
        sbc fr1+1
        bcc ?s

        sty fr0+2
        sta fr0+3

        inc fr0
        bne ?s
        inc fr0+1
        bne ?s

?e      sec
        rts

?s      dex
        bne ?l

        clc
        rts

Główna pętla zajmuje - w zależności od składników - od 624 do 1152 cykli maszynowych.

65C816

int16div
        .aw
        .ib
        rep #$20    ;CPU musi byc w trybie natywnym
        sep #$10

        lda fr1     ;dzielnik musi byc wiekszy od zera
        beq ?e

; <-- czesc pomijalna
        lda fr0     ;dzielnik wiekszy od dzielnej
        cmp fr1     ;daje w wyniku zero, a dzielna
        bcs ?div    ;stanowi reszte

        lda fr0
        sta fr0+2
        stz fr0
        rts
; -->

?div    stz fr0+2   ;kasujemy reszte

        ldx #16

?l      asl fr0
        rol fr0+2

        sec
        lda fr0+2
        sbc fr1
        bcc ?s

        sta fr0+2

        inc fr0
        bne ?s

?e      sec
        rts

?s      dex
        bne ?l

        clc
        rts

Elegancka procedura biblioteczna powinna jeszcze przechowywać na stosie i przed powrotem do miejsca wywołania przywracać rozmiar rejestrów. W powyższym przykładzie pominięto to, żeby nie zaciemniać zagadnienia.

Uwagi

Procedura jest "kompatybilna" z procedurą mnożenia (quod vide).