Μικρά μαθήματα

02 / ΑΚΕΡΑΙΟΙ + ΚΙΝΗΤΗ ΥΠΟΔΙΑΣΤΟΛΗ

Τέσσερα byte στην είσοδο.
Ένας αριθμός BASIC στην έξοδο.

Η σωστή μετατροπή αριθμών ήταν ένας από τους πρώτους πονοκεφάλους του AIS4CBM. Ο αποκωδικοποιητής είχε τα σωστά byte ακεραίου, αλλά η BASIC χρειαζόταν τιμή κινητής υποδιαστολής. Δείτε πώς το fac.asm συνδέει τα δύο.

Commodore 128 · assembly 8502 · Ανάλυση της διαδρομής MMSI 30 bit

01 / ΩΣ ΠΟΥ ΒΟΗΘΑ Η ROM

Δύο byte είναι εύκολα. Το AIS χρειάζεται περισσότερα.

Ο C128 διαθέτει ήδη ρουτίνες μετατροπής ακεραίων σε κινητή υποδιαστολή στη ROM της BASIC. Τιμές ενός byte και ακέραιοι 16 bit έχουν έτοιμες διαδρομές μετατροπής:

Διαδρομές μετατροπής στη ROM του C128
ΕίσοδοςΔιαδρομή ROMΣύμβαση εισόδου
8 bit με πρόσημο$8C68Τιμή στον A, από −128 έως 127.
16 bit με πρόσημοJGIVAYF / $AF03Υψηλό byte στον A, χαμηλό στον Y.
16 bit χωρίς πρόσημοJFLOATC / $AF0FΥψηλό/χαμηλό byte στα $64/$65, X = $90, carry ενεργό.

Ένα byte χωρίς πρόσημο επεκτείνεται σε δύο με μηδενικό υψηλό byte· αυτή τη διαδρομή χρησιμοποιεί το fac.asm. Οι τυπικές ρουτίνες δεν δέχονται αυθαίρετο ακέραιο τεσσάρων byte. Η BASIC αναπαριστά μεγαλύτερους αριθμούς και η ROM διαθέτει χαμηλότερου επιπέδου μαθηματικές λειτουργίες, αλλά αυτός ο πίνακας αλμάτων δεν προσφέρει αντίστοιχη είσοδο τεσσάρων byte.

Το AIS4CBM αποθηκεύει MMSI 30 bit, μήκος 28 bit και πλάτος 27 bit σε τέσσερα byte το καθένα. Η είσοδος μετατροπής ελέγχει το μήκος αποθήκευσης και στέλνει τα μεγαλύτερα πεδία στη δική της ρουτίνα:

fac.asm · επιλογή διαδρομής μετατροπής
lda fragment.fieldLength
cmp #3
bcc !+
jmp big

02 / ΓΝΩΡΙΣΤΕ ΤΟΝ ΠΡΟΟΡΙΣΜΟ

Ο FAC είναι συσσωρευτής εργασίας.

FAC σημαίνει συσσωρευτής κινητής υποδιαστολής. Είναι ο χώρος εργασίας της BASIC για έναν αριθμό. Η μετατροπή κατασκευάζει τα ακόλουθα μέρη του FAC1 στην πραγματική μηδενική σελίδα:

Τα πεδία FAC1 που χρησιμοποιούνται εδώ
ΘέσηΠεριεχόμενο
$63Εκθέτης με πόλωση· το μηδέν δηλώνει τον αριθμό μηδέν.
$64–$67Τέσσερα byte σημαντικού μέρους, πιο σημαντικό πρώτο, με ρητό αρχικό 1 για κανονικοποιημένη μη μηδενική τιμή.
$68Ξεχωριστό πρόσημο· το bit 7 δηλώνει αρνητικό αριθμό.

Για θετικό ακέραιο, βρείτε το υψηλότερο ενεργό bit στη θέση p, με αρίθμηση από το 0. Μετακινήστε το στην κορυφή του σημαντικού μέρους των τεσσάρων byte και αποθηκεύστε τον εκθέτη ως 129 + p. Το σημαντικό μέρος αναπαριστά τώρα τιμή από 1 έως μικρότερη του 2· ο εκθέτης δίνει την κλίμακα.

03 / ΑΚΟΛΟΥΘΗΣΤΕ ΕΝΑΝ ΑΡΙΘΜΟ

123456789, byte προς byte.

Χρησιμοποιήστε 123456789 ως ενδεικτική τιμή μεγέθους MMSI. Τα τέσσερα byte εισόδου είναι 07 5B CD 15, πιο σημαντικό πρώτο. Ο περιγραφέας δηλώνει 30 bit, τέσσερα byte, χωρίς πρόσημο. Το υψηλότερο ενεργό bit είναι στη θέση 26.

Το 123456789 αρχίζει ως 07 5B CD 15. Το υψηλότερο bit είναι το 26, άρα Y=27. Πέντε αριστερές ολισθήσεις δίνουν EB 79 A2 A0. Ο εκθέτης είναι 129+26, δηλαδή 9B δεκαεξαδικό, και το πρόσημο μηδέν.
Τα bit διατηρούν την τιμή τους· η κανονικοποίηση αλλάζει τη θέση τους και καταγράφει την κλίμακα. Όλες οι τιμές byte στο διάγραμμα είναι δεκαεξαδικές. Πλήρες μέγεθος ↗

Η αναζήτηση αφήνει Y = 27, θέση bit με αρίθμηση από το 1. Το πλήθος ολισθήσεων είναι 32 − 27 = 5. Ο εκθέτης γίνεται 129 + 26 = 155 ($9B). Ο FAC1 περιέχει εκθέτη 9B, σημαντικό μέρος EB 79 A2 A0 και πρόσημο 00.

Αν η BASIC αποθηκεύσει αυτή την ακριβή τιμή σε μεταβλητή, τα πέντε byte είναι 9B 6B 79 A2 A0: το θετικό πρόσημο αντικαθιστά το ανώτερο bit. Ο ακέραιος χωρά ακριβώς· η κανονικοποίηση δεν χάνει σημαντικά bit.

04 / Ο ΚΩΔΙΚΑΣ ΤΗΣ ΜΕΤΑΤΡΟΠΗΣ

Εύρεση bit. Ολίσθηση. Ορισμός κλίμακας.

Ακολουθούν αποσπάσματα από το τρέχον src/Include/fac.asm, με απλοποιημένα κενά και χωρίς σχόλια. Μοιράζονται ετικέτες, μεταδεδομένα και μακροεντολές ROM με το υπόλοιπο πρόγραμμα· δεν είναι αυτόνομο αρχείο assembly.

Πριν την αναζήτηση, η big μηδενίζει εκθέτη και πρόσημο, αντιγράφει την είσοδο στο σημαντικό μέρος και τοποθετεί τη μάσκα bit στο δηλωμένο πλάτος. Τα πεδία με πρόσημο ελέγχουν και το bit προσήμου και καλούν Fac1Complement() όταν είναι αρνητικά. Η διαδρομή MMSI χωρίς πρόσημο παραλείπει αυτό το βήμα.

1. Βρείτε το υψηλότερο ενεργό bit

fac.asm · σάρωση του μέτρου
facByte:
!:      bit $64
        bne calculateExponent
        lsr
        bne !+
        lda #128
        inc facByte+1
!:      dey
        bne !--
        jmp reset

Ο A κρατά τη μάσκα bit. LSR τη μετακινεί μέσα στο byte· όταν εξαντληθεί, ο κώδικας ξαναρχίζει από το bit 7 του επόμενου byte. inc facByte+1 τροποποιεί τον τελεστέο διεύθυνσης της BIT. Ο Y παρακολουθεί την εναπομένουσα θέση bit. Αν κανένα bit δεν είναι ενεργό, ο εκθέτης παραμένει μηδέν.

2. Κανονικοποιήστε το σημαντικό μέρος των τεσσάρων byte

fac.asm · ολόκληρη η ρουτίνα shiftLeft
shiftLeft:
{
        sty counter+1
        lda #32
        sec
counter:
        sbc #0
        tay
!:      clc
        ldx #3
!:      rol workingBuffer+1,x
        dex
        bmi !+
        jmp !-
!:      dey
        bne !---
        rts
}

counter+1 γίνεται η αρχική τιμή Y, οπότε η αφαίρεση υπολογίζει 32 − Y. Κάθε πέρασμα αρχίζει από το λιγότερο σημαντικό byte και περιστρέφει προς το πιο σημαντικό. Το carry μεταφέρει το εξερχόμενο bit από το ένα byte στο επόμενο. CLC πριν από κάθε πέρασμα τεσσάρων byte εισάγει μηδέν στο χαμηλό άκρο· η SEC κάνει την αφαίρεση ανεξάρτητη από το προηγούμενο carry.

3. Αποθηκεύστε τον εκθέτη με πόλωση

fac.asm · διατήρηση του Y κατά την κανονικοποίηση και ορισμός εκθέτη
calculateExponent:
        tya
        pha
        jsr shiftLeft
        pla
        tay
        dey
        sty exponentPower+1
        lda #129
        clc
exponentPower:
        adc #0
        sta workingBuffer
        jmp reset

Ο αρχικός Y διατηρείται στη στοίβα όσο εκτελείται η ολίσθηση. DEY μετατρέπει την αρίθμηση από το 1 σε δύναμη με βάση το 0. Η τροποποιημένη ADC προσθέτει 129, με το carry ρητά μηδενισμένο. workingBuffer ορίζεται ως $63, ο εκθέτης FAC1.

05 / ΟΙ ΛΕΠΤΟΜΕΡΕΙΕΣ ΠΟΥ ΜΕΤΡΟΥΝ

Ορίστε σαφώς τη σύμβαση εισόδου.

  • Το πλάτος σε byte διαφέρει από το πλάτος σε bit. Το MMSI 30 bit καταλαμβάνει τέσσερα byte. Ο περιγραφέας λέει στον μετατροπέα πού να αρχίσει την αναζήτηση.
  • Διατηρήστε τη σειρά byte. Εδώ το πιο σημαντικό byte προηγείται. Μια τυπική διεύθυνση 6502 αποθηκεύεται με την αντίστροφη σειρά.
  • Χρησιμοποιήστε την πραγματική μηδενική σελίδα. Ο C128 μπορεί να την ανατοποθετήσει. trans επιλέγει τη σελίδα 0 και επαναφέρει έπειτα τη σελίδα του καλούντος· ο κώδικας που χρησιμοποιεί τον FAC1 πρέπει επίσης να βλέπει τη σωστή σελίδα.
  • Το carry είναι μέρος του υπολογισμού. Οι ρητές εντολές SEC και CLC απομονώνουν την αφαίρεση, τις ολισθήσεις και το άθροισμα εκθέτη από την προηγούμενη κατάσταση του επεξεργαστή.

Διαβάστε τον κώδικα

Οι σύνδεσμοι δείχνουν στο main του δημόσιου αποθετηρίου GitLab. Οι αριθμοί γραμμών μπορεί να αλλάξουν.

  • fac.asm — μεταδεδομένα εισόδου, επιλογή ROM και διαδρομή μεγαλύτερων ακεραίων.
  • getDataByField — αντιγραφή περιγραφέα και byte εισόδου, έπειτα άλμα στη trans.
  • c128macros.asm — γέφυρες ROM και βοηθητική ρουτίνα συμπληρώματος.
  • decoderHeaders.asm — ορισμοί πεδίων MMSI και συντεταγμένων.