home *** CD-ROM | disk | FTP | other *** search
-
- ;****************************************************************************
- ; Vergleichsprogramm Version 1.0 - Cmp
- ; Das Programm vergleicht zwei Binärfiles miteinander und meldet, ob und wo
- ; sie unterschiedlich sind.
- ;
- ; Copyright in 1991 by Dietmar Heidrich.
- ; Dieses Programm ist Bestandteil von OMA V2.0 und nur als Beispiel vorhan-
- ; den. Seine Vervielfältigung, Veränderung oder Verbreitung ist verboten.
- ;
- ; Dieses Cmp kann NICHT gleichzeitig von mehreren Tasks benutzt werden,
- ; wenn es unter der Workbench 1.3 resident gehalten wird. Compress-Tab 8.
- ;****************************************************************************
-
- SECTION CmpCODE,CODE
-
- NOPAGE
- NOLIST
-
- INCLUDE "exec/types.i"
- INCLUDE "exec/alerts.i"
- INCLUDE "exec/tasks.i"
- INCLUDE "libraries/dos.i"
- INCLUDE "libraries/dosextens.i"
- INCLUDE "lvo/exec.i"
- INCLUDE "lvo/dos.i"
-
- LIST
-
-
-
-
- BP EQUR A5
-
- _SysBase EQU 4
-
- TAB EQU 9
- LF EQU 10
- CR EQU 13
- SPACE EQU ' '
- PUFFERGROESSE EQU 10000
- MAXIMUM_ARGUMENTS EQU 6
- MAXIMUM_ARGBUFFER EQU 256
-
-
-
- CALL MACRO
- IFEQ NARG-2
- move.l \2,a6
- ENDC
- IFLE NARG-2
- jsr _LVO\1(a6)
- MEXIT
- ENDC
- FAIL CALL MACRO ERROR
- ENDM
-
-
-
- STRINGLF MACRO
- dc.b '\1',LF,0
- ENDM
-
-
-
-
-
-
-
-
-
-
- ;****************************************************************************
- ; Der Beginn.
-
- Startup
- lea Basisadresse+32768,BP
-
- BASEREG BP
-
-
-
-
-
-
-
-
-
-
- ;****************************************************************************
- ; Variablen.
-
- SECTION CmpBSS,BSS
-
- CNOP 0,4
-
- Basisadresse
-
- _DOSBase ds.l 1
- HauptSP ds.l 1
- _stdout ds.l 1
-
- argvArray ds.l MAXIMUM_ARGUMENTS
- argvBuffer ds.b MAXIMUM_ARGBUFFER
-
-
-
- CNOP 0,4
-
- AnfangBss
-
-
- Seitennummer ds.l 1
- Fehlerflag ds.l 1
-
- Filename1 ds.l 1
- Filename2 ds.l 1
-
- File1 ds.l 1
- File2 ds.l 1
-
- Filepuffer1 ds.b PUFFERGROESSE
- Filepuffer2 ds.b PUFFERGROESSE
-
- Formatierstring ds.b 256
-
-
- CNOP 0,4
-
- EndeBss
-
-
-
-
-
-
-
-
-
-
- ;****************************************************************************
- ; Parse die CLI-Argumente.
-
- SECTION CmpCODE,CODE
-
- ParseArgumente
-
- ; Öffne DOS.
- move.l SP,HauptSP
- movem.l d0/a0,-(SP)
- lea DOSName(PC),a1
- moveq #LIBRARY_VERSION,d0
- CALL OpenLibrary,_SysBase
- move.l d0,_DOSBase
- bne.s 1$
-
- BASEREG OFF
-
- ; Fehler: DOS nicht offen.
- move.l #(AG_OpenLib!AO_DOSLib),d7
- lea AlertWert(PC),a5
- CALL Alert
- addq #2*4,SP ; korrigiere Stack
- moveq #100,d0
- rts ; zurück zum DOS
-
- BASEREG BP
-
- ; Initialisiere Zähler und Zeiger.
- 1$ move.l d0,a6
- CALL Output
- move.l d0,_stdout
- move.l #MAXIMUM_ARGBUFFER-1,d7
- moveq #MAXIMUM_ARGUMENTS-1,d6 ; Argumentzähler
- lea argvArray,a1
- lea argvBuffer,a3
- movem.l (SP)+,d0/a0
- cmp.l d7,d0 ; Kommandozeile zu lang ?
- bhs.s FehlerBufferOverflow ; ja
-
- ; Parse die Argumente.
- moveq #SPACE,d5 ; verkürzt Code
- moveq #'"',d3 ; verkürzt Code
- bra NächstesArgument
-
-
-
- ArgumentSchleife
- move.b (a0)+,d4 ; hole Zeichen
- cmp.b d5,d4 ; legales Zeichen ?
- bls.s NächstesArgument ; nein, nächstes Zeichen
-
- move.l a3,a2 ; Zeiger auf Argumentpuffer-Stelle merken
- cmp.b d3,d4 ; ist es doppeltes Hochkomma ?
- bne.s 1$ ; nein
- bra.s 3$ ; ja
-
-
-
- ; Argument darf mit einem SPACE enden.
- 2$ move.b (a0)+,d4 ; hole Zeichen
- cmp.b d5,d4 ; Argument beendet ?
- bls.s ArgumentEnde ; ja
- 1$ cmp.b #'=',d4 ; ein '=' ist nicht erlaubt
- beq.s FehlerEquateUse ; wenn Fehler
- move.b d4,(a3)+ ; speichere Zeichen
- dbra d0,2$ ; Zeichen übrig ?
- bra.s ArgumentEnde ; nein
-
-
-
- ; Argument ist in doppelte Hochkommata eingefaßt.
- 4$ move.b (a0)+,d4 ; hole Zeichen
- cmp.b d5,d4 ; Argument beendet ?
- blo.s FehlerIllegalArgEnd ; ja, Fehler
-
- ; Endet Argument mit doppeltem Hochkomma ?
- cmp.b d3,d4
- bne.s 5$ ; nein
- subq #1,d0 ; Zeichen übrig ?
- blt.s ArgumentEnde ; nein, alles OK
- move.b (a0)+,d4 ; ja, nächstes Zeichen
- cmp.b d5,d4 ; legales Zeichen ?
- bls.s ArgumentEnde ; ja, alles OK
- bra.s FehlerIllegalArgEnd ; nein, Fehler
-
- ; Ist es ein Stern ?
- 5$ cmp.b #'*',d4
- bne.s 6$ ; nein, speichere Zeichen
- subq #1,d0 ; Zeichen übrig ?
- blt.s FehlerIllegalArgEnd ; nein, Fehler
- move.b (a0)+,d4 ; hole Zeichen
- cmp.b d5,d4 ; Argument beendet ?
- blo.s FehlerIllegalArgEnd ; ja, Fehler
-
- 6$ move.b d4,(a3)+ ; speichere Zeichen
-
- ; Es MUß noch Zeichen geben, oder Fehler.
- 3$ dbra d0,4$ ; Zeichen übrig ?
-
-
-
- FehlerIllegalArgEnd
- lea TextBadArgs(PC),a0
- bra.s ArgumentFehler
-
- FehlerBufferOverflow
- lea TextBufferOverflow(PC),a0
- bra.s ArgumentFehler
-
- FehlerEquateUse
- lea TextEquateUse(PC),a0
- bra.s ArgumentFehler
-
- FehlerTooManyArguments
- lea TextTooManyArgs(PC),a0
-
- ArgumentFehler
- bra Programmende
-
-
-
- ArgumentEnde
- clr.b (a3)+ ; Argumentende
- subq.l #1,d6 ; noch freie Zeiger übrig ?
- ble.s FehlerTooManyArguments ; nein
- move.l a2,(a1)+ ; merke Zeiger auf Argumentstring
-
- NächstesArgument
- dbra d0,ArgumentSchleife ; Zeichen übrig ?
-
- ; Setze die Startwerte.
- lea argvArray,a0
- neg d6
- add #MAXIMUM_ARGUMENTS-1,d6
- move.l d6,d0
-
-
-
-
-
-
-
-
-
-
- ;****************************************************************************
- ; Beginn des Programmes. D0 enthält die Anzahl der CLI-Parameter und A0 den
- ; Zeiger auf das Feld der Zeiger auf die CLI-Argumente.
-
- _main
- ; Initialisierung.
- lea AnfangBss,a1
- move #(EndeBss-AnfangBss)/4-1,d1
- 1$ clr.l (a1)+
- dbra d1,1$
- move.l a0,a2 ; retten
-
- ; Es müssen 2 Argumente sein.
- subq.l #2,d0
- bne FehlerIllegalArgEnd
- move.l (a0)+,Filename1
- move.l (a0)+,Filename2
-
- ; Lösche die Signale.
- moveq #0,d0
- move.l #SIGBREAKF_CTRL_D!SIGBREAKF_CTRL_C,d1
- CALL SetSignal,_SysBase
-
- ; Öffne das erste File.
- move.l Filename1,d1
- move.l d1,a4
- move.l #MODE_OLDFILE,d2
- CALL Open,_DOSBase
- move.l d0,File1
- bne.s 2$
- ; Fehler: File nicht offen.
- 3$ CALL IoErr
- move.l a4,-(SP)
- move.l d0,-(SP)
- lea TextErrorOpen(PC),a0
- bra Programmende
-
- ; Öffne das zweite File.
- 2$ move.l Filename2,d1
- move.l d1,a4
- move.l #MODE_OLDFILE,d2
- CALL Open
- move.l d0,File2
- beq.s 3$
-
-
-
-
- ; Fülle die Puffer. A4 & A3 sind Pufferzeiger, D7 & D6 Restbytezähler.
- 8$ move.l File1,d1
- move.l Filename1,a2
- lea Filepuffer1,a4
- move.l a4,a0
- bsr FuelleFilepuffer
- move.l d0,d7
- move.l File2,d1
- move.l Filename2,a2
- lea Filepuffer2,a3
- move.l a3,a0
- bsr FuelleFilepuffer
- addq.l #1,Seitennummer
- move.l d0,d6
-
- ; Sind beide Längen Null ?
- suba.l a0,a0
- or.l d7,d0
- beq.s Programmende ; ja, Files zu Ende und beide gleich
-
-
- ; Sind die Längen verschieden ?
- cmp.l d6,d7
- beq.s 4$ ; nein (BNE ist falsch)
- lea TextDifferentLength(PC),a0
- bsr Stringausgabe
- move d6,d0
- cmp d6,d7
- bhs.s 0$
- move d7,d0
- 0$ moveq #0,d1 ; mache BNE falsch
- bra.s 6$
-
- 7$ cmp.b (a3)+,(a4)+
- 6$ dbne d0,7$
- bne Verschieden
- suba.l a0,a0
- bra Programmende ; Files zu Ende
-
-
- ; Vergleiche die Bytes.
- 5$ cmp.b (a3)+,(a4)+
- 4$ dbne d6,5$
-
- beq 8$ ; wenn bis hier gleich
-
-
-
- Verschieden
- ; Berechne die Byteposition.
- move.l Seitennummer,d0
- subq.l #1,d0 ; da immer eine Seite zuviel
- move.l d0,d1
- mulu #PUFFERGROESSE,d0
- swap d1
- mulu #PUFFERGROESSE,d1
- swap d1
- clr d1
- add.l d1,d0 ; Beginn der Seite
- lea Filepuffer1,a0
- sub.l a0,a4
- subq #1,a4 ; da A4 einen zu weit zeigte
- add.l a4,d0
- move.l d0,-(SP)
- lea TextFilesDiffer(PC),a0
- ; und durchfallen...
-
-
-
-
-
-
-
-
-
-
- ;******************************************************************************
- ; Beende das Programm.
- ; Eingabe: A0 zeigt auf den Fehlerstring oder ist Null.
-
- Programmende
- move.l _DOSBase,a6
- move.l a0,Fehlerflag ; existiert String ?
- beq.s 1$ ; nein
- bsr Stringausgabe
-
- ; Schließe File 1.
- 1$ move.l File1,d1
- beq.s 2$
- CALL Close
-
- ; Schließe File 2.
- 2$ move.l File2,d1
- beq.s 3$
- CALL Close
-
- ; Schließe DOS.
- 3$ move.l _DOSBase,d0
- beq.s 4$
- move.l d0,a1
- CALL CloseLibrary,_SysBase
-
- ; Zurück ins DOS.
- 4$ move.l Fehlerflag,d0 ; trat Fehler auf ?
- beq.s 5$ ; nein, D0=0 und fertig
- moveq #RETURN_FAIL,d0 ; ja, melde AmigaDOS einen Fehler
- 5$ move.l HauptSP,SP
- rts
-
-
-
-
-
-
-
-
-
-
- ;******************************************************************************
- ; Fülle einen Filepuffer.
- ; Eingabe: A0 zeigt auf den Puffer.
- ; A2 zeigt auf den Namen.
- ; D1 enthält den Filezeiger.
- ; Ausgabe: D0 enthält die Restbytes.
-
- FuelleFilepuffer_REG REG d1-d3/a0-a1/a6
-
- FuelleFilepuffer
- movem.l FuelleFilepuffer_REG,-(SP)
- move.l a0,d2 ; Pufferzeiger
- move.l #PUFFERGROESSE,d3
- CALL Read,_DOSBase
- moveq #-1,d1
- cmp.l d0,d1 ; Lesefehler ?
- beq.s 1$ ; ja
- movem.l (SP)+,FuelleFilepuffer_REG
- rts
-
- ; Lesefehler im File.
- 1$ CALL IoErr
- move.l a2,-(SP) ; Filename
- move.l d0,-(SP)
- lea TextReadError(PC),a0
- bra Programmende
-
-
-
-
-
-
-
-
-
-
- ;******************************************************************************
- ; Konvertiere ein Langwort in einen maximal 11 Stellen langen Dezimalstring.
- ; Die Routine vermeidet überflüssige Nullen am Zahlenanfang wie z.B. 0019.
- ; Eingabe: D0 enthält das Langwort.
- ; A0 zeigt auf den Ablagestring.
- ; Ausgabe: A0 zeigt direkt hinter den Dezimalstring. Der Dezimalstring landet
- ; im Ablagestring.
-
- ErzeugeDezimalZahl_REG REG d0-d4/a1
-
- ErzeugeDezimalZahl
- movem.l ErzeugeDezimalZahl_REG,-(SP)
- lea DezimalTabelle(PC),a1
- moveq #9,d1 ; Stellenzähler
- 2$ cmp.l (a1)+,d0 ; ist Stellenwertigkeit zu hoch ?
- bhs.s 1$
- dbra d1,2$ ; ja, nächste Stelle
- moveq #0,d1 ; hier landen wir, falls D0 = 0
-
- 1$ subq #4,a1 ; ergibt die richtige Stellenwertigkeit
-
- 5$ move.l d0,d3 ; Rest der Zahl retten
- moveq #'0',d2
- move.l (a1)+,d4 ; Stellenwertigkeit holen
- bra.s 3$
-
- 4$ addq #1,d2 ; Ziffer höher stellen
- 3$ move.l d3,d0 ; Rest der Zahl
- sub.l d4,d3 ; ist Stellenwertigkeit zu hoch ?
- bcc.s 4$ ; nein
-
- move.b d2,(a0)+ ; ja, erhaltene Ziffer in Ausgabepuffer
- dbra d1,5$ ; alle Stellen durch ?
-
- movem.l (SP)+,ErzeugeDezimalZahl_REG
- rts
-
-
-
-
-
-
-
-
-
-
- ;******************************************************************************
- ; Die Stringausgabe formatiert einen String und gibt ihn auf _stdout aus.
- ; Eingabe: A0 zeigt auf den auszugebenden String.
-
- Stringausgabe_REG REG d0-d3/a0-a3/a6
-
- Stringausgabe
- movem.l Stringausgabe_REG,-(SP)
- move.l a0,a1
- lea Formatierstring,a0 ; hier hinein kommt der fertige String
- move.l a0,d2 ; merken für DOS-Write und Längenberechnung
-
- ; Beachte, daß 9 Register auf den Stack gerettet wurden.
- lea 4+4*9(SP),a3 ; Zeiger auf die Parameter
- bra.s 1$
-
-
-
- ; Setze Dezimalzahl ein.
- 2$ move.b (a1)+,d0 ; hole Zeichen
- move.b d0,d1
- bclr #5,d1 ; wandele in Großbuchstaben
- cmp.b #'D',d1 ; soll eine Dezimalzahl eingesetzt werden ?
- bne.s 4$ ; nein
- move.l (a3)+,d0 ; hole Parameter (Dezimalzahl)
- bsr ErzeugeDezimalZahl ; und schreibe Dezimalstring nach A0
- bra.s 1$ ; hole das nächste Zeichen
-
-
- ; Setze einen String ein.
- 4$ cmp.b #'S',d1 ; soll ein String eingesetzt werden ?
- bne.s 5$ ; nein
- move.l (a3)+,a2 ; hole Parameter (Stringzeiger)
- 6$ move.b (a2)+,(a0)+ ; kopiere Zeichen
- bne.s 6$ ; bis String zu Ende
- subq #1,a0 ; zeigt jetzt direkt hinter String
- bra.s 1$
-
-
- ; Setze Hexzahl ein.
- 5$ cmp.b #'X',d1
- bne.s 3$
- move.l (a3)+,d0 ; hole Parameter
- moveq #8-1,d1 ; ein Langwort hat 8 Nibbles
- 7$ rol.l #4,d0
- move.b d0,d3
- and.b #%1111,d3
- cmp.b #10,d3
- blt.s 8$
- addq #('A'-'0'-10),d3
- 8$ add.b #'0',d3
- move.b d3,(a0)+ ; Nibble ausgeben
- dbra d1,7$ ; bis alle Nibbles durch sind
-
-
- ; Hole ein Zeichen.
- 1$ move.b (a1)+,d0 ; hole Zeichen
- cmp.b #'%',d0 ; ist es '%' ?
- beq.s 2$ ; ja, ersetze einen Parameter
- ; Speichere das Zeichen nur.
- 3$ move.b d0,(a0)+ ; Zeichen speichern
- bne.s 1$ ; bis String zu Ende ist
-
-
- ; Wir sind fertig mit Formatieren.
- subq #1,a0 ; da A0 einen zu weit zeigt
- move.l a0,d3
- sub.l d2,d3 ; ergibt Stringlänge
- move.l _stdout,d1 ; Filezeiger
- CALL Write,_DOSBase ; scher dich nicht darum, ob's klappt
- movem.l (SP)+,Stringausgabe_REG
- rts
-
-
-
-
-
-
-
-
-
-
- ;******************************************************************************
- ; Die Tabellen.
-
- AlertWert dc.l -1
-
- DezimalTabelle
- dc.l 1000000000,100000000,10000000,1000000,100000,10000,1000,100,10,1
-
-
-
-
-
-
-
-
-
-
- ;******************************************************************************
- ; Hier kommen die Texte.
-
- DOSName DOSNAME
-
-
- IFD ENGLISCH
-
- TextBadArgs STRINGLF <Bad args>
- TextBufferOverflow STRINGLF <Argument buffer overflow>
- TextEquateUse STRINGLF <Illegally used ''=''>
- TextTooManyArgs STRINGLF <Too many arguments>
-
- TextErrorOpen STRINGLF [DOS error %d opening file <%s>]
- TextReadError STRINGLF [DOS error %d reading file <%s>]
- TextDifferentLength STRINGLF [Files have different length]
- TextFilesDiffer STRINGLF [Files differ at byte $%x]
-
- ELSE
-
- TextBadArgs STRINGLF <Falsche Argumente>
- TextBufferOverflow STRINGLF <Argumentpuffer-Überlauf>
- TextEquateUse STRINGLF <Unzulässiges ''=''>
- TextTooManyArgs STRINGLF <Zu viele Argumente>
-
- TextErrorOpen STRINGLF [DOS-Fehler %d beim Öffnen von File <%s>]
- TextReadError STRINGLF [DOS-Lesefehler %d im File <%s>]
- TextDifferentLength STRINGLF [Files sind verschieden lang]
- TextFilesDiffer STRINGLF [Files sind verschieden am Byte $%x]
-
- ENDC
-
-
-
-
-
-
-
-
-
-
- ; Ende des Programmes
-
- END
-
-