Mac65 Macros


Mac65 Macros

von Bernd » Mi 3. Dez 2008, 23:51
Hallo zusammen,

ist zwar schon einige Zeit her aber dieses Macro für den M65 möchte ich noch mal vorstellen.
Im File Kernel.M65 befindet sich eine aussergewöhliche zwei Bytes Vergleichsfunktion. Aufgerufen wird es wie folgt im Hauptprogramm:

50 DEQCMP QQPASS,QQPASS+2
60 Bne DaEntlang

Hier die Makros dazu. Der Vergleich von low und high Bytes über STA QQCFLG, PLA, AND QQCFLG, PHA, PLP müsste jedem Programmiererherz höher schlagen lassen.

1108 .MACRO DEQCMP
1109 DPOKE QQCMP,%1
1110 DPOKE QQCMP+2,%2
1111 LDA QQCMP
1112 CMP QQCMP+2
1113 PHP
1114 LDA QQCMP+1
1115 CMP QQCMP+3
1116 PHP
1117 PLA
1118 STA QQCFLG
1119 PLA
1120 AND QQCFLG
1121 PHA
1122 PLP
1123 .ENDM

6028 .MACRO DPOKE
6029 .IF [%2]>256
6030 LDA %2
6031 STA %1
6032 LDA %2+1
6033 STA %1+1
6034 .ELSE
6035 LDA #%2
6036 STA %1
6037 LDA #0
6038 STA %1+1
6039 .ENDIF
6040 .ENDM

Die Jungs hatten was drauf,
Bernd

PS:@Dietrich - wie war das nochmal mit dem einfachen Vergleichen zweier 16bit Variablen?

Re: Mac65 Macros

von HiassofT » Fr 5. Dez 2008, 00:36
Hi!

Bernd hat geschrieben:Der Vergleich von low und high Bytes über STA QQCFLG, PLA, AND QQCFLG, PHA, PLP müsste jedem Programmiererherz höher schlagen lassen.

Also entweder übersehe ich gerade etwas wesentliches oder der Code ist einfach nur kompliziert und falsch. Das Ergebnis Z-Flag (also Gleichheit/Ungleichheit) stimmt zwar, aber die anderen Flags sind nicht korrekt.

Die korrekte und (viel einfachere) Lösung muß meiner Meinung nach so aussehen:
Code: Alles auswählen
LDA VAR1+1
CMP VAR2+1
BNE weiter
LDA VAR1
CMP VAR2
weiter = *


6028 .MACRO DPOKE

Hilfe, was soll das? "DPOKE VAR, 255" schreibt 255 in VAR und 0 in VAR+1. "DPOKE VAR,256" schreibt 0 in VAR und 1 in VAR+1, aber "DPOKE VAR,257" schreibt nicht 1 in VAR und 1 in VAR+1 sondern den Inhalt der Adresse 257 in VAR und den Inhalt von 258 in VAR+1...

Ich glaube, da hatten die Programmierer gerade ziemlich schlechtes Kraut geraucht (oder es war als "Kopierschutz" gedacht, solchen Code will freiwillig keiner lesen)...

so long,

Hias

von Dietrich » Fr 5. Dez 2008, 02:15
HiasSoft hat geschrieben:(oder es war als "Kopierschutz" gedacht, solchen Code will freiwillig keiner lesen)...

Genau das hab ich auch gedacht, als ich diesen gruseligen Code gesehen habe. Bin nämlich gerade dabei "Koronis Rift" ein wenig aufzuräumen und ein paar kleine Änderungen einzubauen. Da ist auch echt kurioser Code drin.

@Bernd: Zwei 16-Bit-Werte v1 und v2 auf < zu vergleichen, geht so am einfachsten:
Code: Alles auswählen
lda v1
cmp v2
lda v1+1
sbc v2+1
bcc v1_ist_kleiner_als_v2

Wenn man zusätzlich die Differenz haben will, kann man statt cmp v2 auch (z.B.) sec: sbc v2: tax schreiben.

Gruß Dietrich

von Erhard » Fr 5. Dez 2008, 12:22
Hi,

ich galube nicht, daß ein Mensch sich diesen Gruselcode direkt ausgedacht hat. Sowas ist eher das Resultat eines Crossompilers, dem Transport über mehrere Plattformen hinweg oder des Compilierens aus einer Hochsprache.

Windows wurde sicher ebenso gemacht. Stell sich einer vor, bei ordentlicher Programmierung würde W2K auf eine Diskette passen :-))

Viele Grüße

Erhard

von Bernd » Mi 10. Dez 2008, 00:43
Hallöchen,

der Code stammt aus der Mac65 Toolkit und ist für Basic "Aufsteiger" gedacht gewesen.
DPoke = Double Poke = Word Poke....sollte eine Vereinfachung darstellen.
Was den Programmcode betrifft, es wurde von OSS entwickelt und funktioniert.

Der Vergleich von zwei Bytes sollte kompatibel zum normalen 1 Byte vergleich sein, daher wohl der große Aufwand.

Der erstellte Code ist natürlich unübersichtlicher und für Assembler Proggies ein "Witz".
Jedoch ist der Quelltext mit
50 DEQCMP QQPASS,QQPASS+2
60 Bne DaEntlang
doch einfacher zu lesen und damit übersichtlicher oder?
Ein Vorteil musste ja die Toolkit haben sonst hätte sie ja keiner gekauft.

Was den Vergleich angeht habe ich bislang Hias Beispiel benutzt.
Aus Dietrich´s Assembler Zeilen entsteht der kürzeste Code, Danke dafür, man lernt nie aus.

Um alles zu zeigen was es an Befehlen gibt habe ich das Handbuch als PDF-Datei (10MB) erstellt.
@Carsten: Die Datei fehlt noch auf deiner Atari-Wiki Seite.

Viele Grüße,
bernd

von HiassofT » Mi 10. Dez 2008, 02:59
Hi Bernd!

Bernd hat geschrieben:der Code stammt aus der Mac65 Toolkit und ist für Basic "Aufsteiger" gedacht gewesen.
DPoke = Double Poke = Word Poke....sollte eine Vereinfachung darstellen.

Ich muss mir die Doku zum Toolkit mal genauer ansehen, würde mich interessieren was dieses Makro eigentlich machen sollte. Das mache ich aber später mal, bin gerade recht müde.

Um die Rätselstunde aber zu verkürzen, hier die Auflösung (ohne in die Doku zu schauen): Das Makro vergleicht nicht etwa 2 16-bit Werte miteinander, sondern 2x2 Bytes (ich nenne sie hier einfach mal A, B, C, D, abgelegt in dem übergebenen Parameter mit den Offsets 0, 1, 2, 3 - wenn das DPOKE Makro keinen Mist baut).

Jetzt werden A mit C und B mit D verglichen. Nach dem Makro sind die Flags so gesetzt, daß Z (also "Gleichheit") dann gesetzt ist, wenn A=C UND B=D. Soweit so gut, für die Gleichheits-Prüfung stimmt das auch. Aber interessant wird's bei den anderen Flags: C ("Grösser"): ist 1 wenn A>=C UND B>=D. Und genauso nochmal für das N Flag.

Wenn man sich von dem Code nicht zusehr verwirren lässt, ist es gleich auf den ersten Blick klar, wieso das kein korrekter 16-bit Vergleich ist.

Im von mir geposteten Code wird zuerst das High-Byte verglichen, nur wenn da Gleichheit besteht wird das Low-Byte angeschaut. Ist wie im Supermarkt: Als erstes auf die Zahl vor dem Komma schauen, nur wenn da zwei Produkte gleich teuer sind schaut man auf die Cent-Stelle. Wenn eines 2,xx EUR kostet und das andere 3,yy EUR, ist es egal was die Cent-Stelle sagt - maximal kann das 2,99 zu 3,00 ausgehen, und da ist 2,99 immer noch der kleinere Wert.

Aber zurück zur DEQCMP Routine. Nehmen wir mal folgendes Beispiel: Zahl1 = $0100 und Zahl 2 = $00FF. Ich betrachte hier nur mal Z und C Flag, das N spare ich mir :-)

Zuerst wird das Low-Byte von Zahl 1 mit dem Low-Byte von Zahl 2 Verglichen: $00 mit $FF. Gleich sind sie nicht, also is Z=0. $00 ist kleiner als $FF, also ist C=0. Nun die High-Bytes: $01 ist nicht $00, also wieder Z=0. $01 ist >= $00, also C=1.

Zum Schluss werden die Ergebnisse verknüpft: zuerst Z=0 AND Z=0, ergibt Z=0. Dann C=0 AND C=1 ergibt C=0.

Was heisst das also? Erstmal (Z-Flag), daß beide Werte ungeleich sind. Eh klar, das haben wir erwartet.

Und was noch? Da das C-Flag 0 ist, ist also $0100 kleiner als $00FF. Umpf. Und ich bin der Weihnachtsmann :-)


Aus Dietrich´s Assembler Zeilen entsteht der kürzeste Code, Danke dafür, man lernt nie aus.

Dem schliesse ich mich an, auch ich kannte den Trick noch nicht - das ist wirklich kurzer, feiner Code!

so long,

Hias

von Bernd » Mi 10. Dez 2008, 21:50
Hallo Hias,

ich werde deine Daten in ein Assemblerprogramm umsetzen und anschließend Tracen. Das Ergebnis lege ich dann hier ab.
Was sichbar wird ist immer einfacher zu verstehen.
Nach der Anleitung hier die Toolkit Daten - ATR-File und PDF-File zusammengefasst.

Viele Grüße,
Bernd

von HiassofT » Mi 10. Dez 2008, 21:57
Hallo Bernd!

Bernd hat geschrieben:ich werde deine Daten in ein Assemblerprogramm umsetzen und anschließend Tracen. Das Ergebnis lege ich dann hier ab.

Ich hatte heute Nachmittag mal kurz einen Blick in das PDF geworfen, der DEQCMP Befehl ist darin garnicht beschrieben. Dann habe ich mir die Files auf der Toolkit Disk angesehen, intern wird der DEQCMP nur von den beiden Macros IFEQ und IFNE verwendet.

Insofern ist die Verwendung des Macros DEQCMP OK, wenn auch reichlich umständlich. Ich tippe auch darauf, daß der Name DEQCMP auf "EQual CoMParison" schliessen soll.

Achja, ein Bug in DPOKE ist mir noch aufgefallen: Statt >256 muss es >=256 heissen. In dem Fall DPOKE var,256 wird nämlich 0 in VAR und VAR+1 geschrieben.

so long,

Hias