Ξεκλείδωμα της πρόσβασης ASIC/RMR2 σε μοντέλα Amstrad GX/Plus

Γεια χαρά!

Έπεσα πάνω στο Programming:Unlocking ASIC. Πολύ ωραίο πράγμα εκεί στις βελτιστοποιημένες ρουτίνες! :heart_eyes:

Και ορίστε η δική μου συνεισφορά στο θέμα.

Όπως αναφέρεται στο σχετικό νήμα του παλιού φόρουμ, είναι ευθύνη αυτού που καλεί τη ρουτίνα
να διαχειριστεί τα interrupts, οπότε όλα τα DI/EI φεύγουν! -2 bytes

Υπενθυμίζουμε ότι η πλήρης αλληλουχία ξεκλειδώματος του RMR2 που πρέπει να γραφτεί στη θύρα I/O #BCxx είναι:
NZB, #00,#FF,#77...#8A, STATE (#CD), EOK

NZB: Οποιαδήποτε τιμή εκτός από μηδέν.
STATE: Το #CD ξεκλειδώνει (οποιαδήποτε άλλη τιμή κλειδώνει).
EOK: Πρέπει να σταλεί για να βγει το ASIC από την αλληλουχία ξεκλειδώματος και να επιστρέψει στην επιλογή καταχωρητή CRTC I/O. Μπορεί να είναι οποιαδήποτε τιμή.

Η κλασική βελτιστοποιημένη ρουτίνα δεν εκμεταλλεύεται ορισμένες ιδιότητες της αλληλουχίας ξεκλειδώματος. Όπως:

  • Βάζουμε τα δεδομένα της αλληλουχίας αμέσως μετά το τέλος της ρουτίνας, με ένα RET, δηλαδή έναν opcode &C9, όχι μηδέν, χμμ… μου φαίνεται για NZB! : -1 byte
  • Γιατί να αποθηκεύσουμε την τιμή EOK στα δεδομένα της αλληλουχίας; Δεν μας νοιάζει ποια τιμή είναι, θα στείλουμε ό,τι βρούμε: -1 byte

Αυτό μας δίνει μια ελαφρώς πιο συμπαγή έκδοση:

				; Send a 17 bytes sequence to I/O port #BCxx to unlock RMR2
				; register access. KISS approach using a table of raw values.
				;
				; Size: 28 bytes
				; Time: 178 µs
				;
				; Output:
				;  BC=&BC00
				;  Trashes HL and Flags 
rmr2_unlock:
				ld bc,&BC00+17
				ld hl,_rmr2_data_key
_rmr2_send_key		inc b
					outi
					dec c
					jr nz,_rmr2_send_key
_rmr2_data_key	ret		; This opcode is also used as SYNC/NZB value (#C9)
				db 0, &FF,&77,&B3,&51,&A8,&D4,&62,&39,&9C,&46,&2B,&15,&8A
_rmr2_data_lock	db 205	; 205 to Unlock, anything else to lock

				; The routine will over-read one byte at this location
				; to retrieve an EOK value, necessary for proper unlocking.

Και τώρα, στα 28 bytes, αυτή η απλή και φιλική ρουτίνα κάνει τις βελτιστοποιημένες να μοιάζουν με… Τέλος πάντων, δεν έχει σημασία. (σας αγαπάμε ακόμα!)

Αλλά η ρουτίνα επανυλοποίησης του LFSR από τον @Urusergi μου έβαλε ιδέες. Υπάρχουν τόοοσοι πολλοί τρόποι και κόλπα με bit για να υλοποιήσεις αυτό το μικρό LFSR, που μπορεί να υπάρχουν ακόμα πιο σύντομες παραλλαγές εκεί έξω…

…μερικές μέρες, κλάματα και αιμορραγίες από τη μύτη αργότερα: λοιπόν, όχι και τόσοι πολλοί όπως φαίνεται!
Βρήκα μόνο μία:

				; Software re-implementation of the LFSR logic described in
				; the Amstrad Patent (GB2243701A). It generates a 15 bytes
				; sequence as verified by the ASIC to unlock RMR2 access.
				;
				; Designed by Urusergi
				; Modified by Grim (shaving a single byte, pfew!)
				;
				; Size: 27 bytes
				; Time: 389 µs
				;
				; Output:
				;  BC=&BCFF
				;  Trashes HL and AF
rmr2_unlock:
				ld bc,&BCFF
				out (c),c ; SYNC/NZB
				out (c),0 ; SYNC/NUL
				ld a,c
_rmr2_send_key
					out (c),a
					ld h,a
					add hl,hl
					rra
					add hl,hl
					ld l,a
					xor h
					and &F7
					xor l
					add a,h
					and &88
					xor l
					cp c
					jr nz,_rmr2_send_key
				ret

Προσπάθησα να ξεφορτωθώ τον (χαριτωμένο) έλεγχο εξόδου cp c και να χρησιμοποιήσω κάποιο flag μετά το τελευταίο xor l, αλλά μέχρι στιγμής απέτυχα. Το cp c συνεχίζει να ζει! :slight_smile:

1 «Μου αρέσει»

Βιαστική βελτιστοποίηση είναι η ρίζα κάθε κακού.

Χρειάζεται να ξεκλειδώσετε το ASIC ακριβώς μία φορά. Δεν υπάρχει κανένας λογικός λόγος να το κλειδώσετε ξανά.

Το να γλιτώσετε μερικά bytes είναι εξαιρετικά απίθανο να αποφέρει κάτι, εκτός ίσως από κάποιο περίεργο σενάριο τύπου 4K demo, οπότε σε αυτή την περίπτωση τα μειονεκτήματα των μηχανημάτων Plus που δεν διαθέτουν έτοιμες ρουτίνες ROM τις οποίες μπορείτε να καλέσετε για τέτοιες βασικές λειτουργίες, θα εξανεμίσουν συνήθως οποιοδήποτε πλεονέκτημα σε σχέση με το να γράψετε απλά τυπικό κώδικα CPC.

Βλέπω μια πιθανή περίπτωση χρήσης για το κλείδωμα του ASIC μετά την επαναφορά ορισμένων λειτουργιών. Αυτό το σενάριο πιθανότατα περιλαμβάνει democode του CPC που στόχο έχει να είναι συμβατό με το CRTC Type 3, ενώ σκοπίμως καταχράται το GateArray RMR-bit 5 για ασαφείς λόγους βελτιστοποίησης, κάτι που θα μπορούσε να προκαλέσει σημαντικά προβλήματα εάν το ASIC παραμείνει ξεκλείδωτο.

Οπότε έχεις δίκιο, σίγουρα δεν υπάρχει κανένας λογικός λόγος :slight_smile:

Αν ο κώδικάς σου είναι ενήμερος για το ASIC, τότε πιστεύω ότι δύσκολα θα βρεις μια ρεαλιστική περίπτωση όπου θα χρειαστεί να στείλεις μια τιμή που θα διαταράξει το RMR2. Και είναι ακόμα πιο απίθανο μια τέτοια ενέργεια να υπερτερεί της επιβάρυνσης του εκ νέου ξεκλειδώματος του ASIC την επόμενη φορά που θα χρειαστεί να αλλάξεις οποιοδήποτε από τα χαρακτηριστικά Plus.

Είναι απλώς ένα από αυτά τα σενάρια που δεν βγάζουν και πολύ νόημα.

Ο προγραμματισμός demo δεν χρειάζεται να βγάζει νόημα, αρκεί να τρέχει γρήγορα. Ειδικά στο beam-racing, συνήθως προσπαθείς να στριμώξεις και να πακετάρεις όσα περισσότερα δεδομένα γίνεται στους καταχωρητές του Z80 (είναι γρήγοροι), επαναχρησιμοποιώντας τους και καταχρώμενος τη λειτουργία τους στο έπακρο. Και τότε, η εντολή GA που χρησιμοποιείς δεν είναι μόνο αυτό, αλλά λειτουργεί ταυτόχρονα και ως σκιώδης διεύθυνση I/O για μια άλλη συσκευή, ελέγχει bits στη θύρα PPI Port C και ό,τι άλλο μπορείς να φανταστείς. Κάθε bit μέτρα.

Επίσης, μόνο ο αρχικός κώδικας του demo σου για τον CPC χρειάζεται να αναγνωρίζει το ASIC (για να βεβαιωθείς ότι το υλικό είναι σταθερό πριν αναλάβεις τον έλεγχο)· οτιδήποτε μετά από αυτό μπορεί με ασφάλεια να θεωρήσει ότι πρόκειται για έναν CPC-GateArray, όπου το bit-5 της εντολής του δεν έχει καμία επίδραση.

Επομένως, δεν τίθεται θέμα ξεκλειδώματος/κλειδώματος του ASIC κάθε φορά που θέλεις να «πειράξεις» κάτι σε αυτό — το κάνεις μόνο μία φορά. Το μόνο που χρειάζεται είναι η σωστή ρύθμιση του υλικού πριν τρέξει ο κύριος κώδικάς σου για CPC (όχι Plus). Δεν υπάρχει κάποια επιβάρυνση (overhead) που πρέπει να σταθμίσεις εδώ.

Syngharitīria Grimmy! :clap:

Tha stoichimatiza to d*** mou oti h routina mou den ginotan na beltiiōthei. Pálitukhe pou den to ekana :sweat_smile:

Me ekane kai gelasa :joy:. Me thymizei ekeines tis imeres :face_with_spiral_eyes:

Blepo oti o @Longshot edimiourgyse episis ti diki tou routina. Ouaou! Iksera oti h khrisi mias diplis leksis tha ekane dynati tin ολοκληρωση tis alakolouthias pou i routina tou Madram khedon kataphere, all_a fantastika oti tha katatalambane seismika perissotero khoro. Mpravo!

Ευχαριστώ @Urusergi!

Πράγματι, η χρήση της διπλής λέξης επιτρέπει τη μείωσή του στα 28 bytes παραμένοντας πλήρως δυναμικό. Το κύριο πλεονέκτημα είναι ότι μπορεί επίσης να ξανακλειδώσει το ASIC εν κινήσει μέσω HL (χωρίς patching στη RAM) και εξοικονομεί κύκλους CPU (349 µs έναντι 389 µs).

Αλλά αυτή η προσέγγιση LFSR των 27/28 byte είναι σίγουρα μια έξυπνη συμπίεση για ένα αμιγώς στιγμιαίο (one-shot) ξεκλείδωμα!

1 «Μου αρέσει»