;*************************************************************************
;*
;* Dieses Programm ist Public Domain und wurde mit dem Profimat-Assembler
;* von Data Becker erstellt. Das Kopieren für den privaten
;* Gebrauch ist erlaubt. Sollen das Programm oder Teile daraus für
;* kommerzielle Zwecke verwendet werden, bitte ich darum, sich mit
;* mir in Verbindung zu setzen.
;*
;* © 1988 Richard Englert, Flößaustraße 160, 8510 Fürth, Tel.:0911/708255
;*
;* letzte Änderung: 06-06-1988
;*
;* CRF erlaubt es CON:`s oder RAW:`s zu suchen (besser: suchen zu lassen!)
;* und zu verändern. (Keine lange Sucherei mit einem Diskmonitor mehr!)
;*
;* Nach dem Start von CRF fragt das Programm zuerst nach dem Filenamen
;* der Datei die untersucht werden soll.
;* Wird ein CON: oder RAW: gefunden, fragt CRF ob es verändert werden
;* soll, nachdem es den Text ausgegeben hat.
;* Soll es verändert werden, gibt CRF die maximale Länge der Eingabe
;* an und man kann einen eigenen Text mit den Koordinaten- und Aus-
;* dehnungsdaten für das Window angeben.
;*
;* Format:  x/y/b/h/wname
;*
;*          x: x-Koordinate
;*          y: y-Koordinate
;*          b: Breite
;*          h: Höhe
;*      wname: Name des Windows
;*
;* CON: oder RAW: muß nicht mit eingegeben werden.
;*
;* Danach sucht CRF nach weitern CON:`s/RAW:`s, die dann auf die gleiche
;* Art und Weise verändert werden können.
;* Wird nichts weiter gefunden, schreibt CRF die veränderte Datei unter
;* dem gleichen Namen mit der Extension .CR in das gleiche Verzeichnis
;* in der die ursprüngliche Datei steht.
;*
;* Wurde nichts verändert, oder keine CON:`s/RAW:`s gefunden, beendet
;* CRF seine Arbeit, ohne weitere Sicherungsarbeiten nachdem man
;* RETURN gedrückt hat.
;*
;*************************************************************************

 INCLUDE 'ram:Amiga.ASM'

; AmigaDOS-Funktionen definieren:

_LVOOpenLibrary   EQU -552
_LVOCloseLibrary  EQU -414
_LVOOutput        EQU -60
_LVOWrite         EQU -48
_LVOOpen          EQU -30
_LVOClose         EQU -36
_LVORead          EQU -42
_LVOAllocMem      EQU -198
_LVOFreeMem       EQU -210
_LVOLock          EQU -84
_LVOExamine       EQU -102
_LVOUnLock        EQU -90
_LVODeleteFile    EQU -72
_LVOWaitForChar   EQU -204

; einige Konstanten:

MODE_OLD          EQU 1005
MODE_NEW          EQU 1006
MEMF_PUBLIC       EQU 1<<0
MEMF_CLEAR        EQU 1<<16

;*****************************************************************
;Hauptprogramm:
;*****************************************************************

 INIT_AMIGA

; Dos-Library öffnen:

 LEA DosName,A1
 MOVEQ #0,D0
 CALLSYS OpenLibrary
 MOVE.L D0,DosBase
 BEQ EXIT

; Speicher für Tastatureingabepuffer
; und File-Info-Block reservieren

 MOVE.L #516,D0
 MOVE.L #(MEMF_PUBLIC|MEMF_CLEAR),D1
 LINKSYS AllocMem,ExecBase
 TST.L D0                      ;D0 = 0 ,kein Speicher mehr, Ende
 BEQ EXIT
 MOVE.L D0,CmdBuf          ;Adresse des Blocks in 'CmdBuf' sichern

 ADD.L #256,D0
 MOVE.L D0,FIB

; CON:-Window für Benutzer-Dialog öffnen:

 MOVE.L #WName,D1
 MOVE.L #MODE_OLD,D2
 LINKSYS Open,DosBase
 TST.L D0
 BEQ EXITM
 MOVE.L D0,WHandle             ;Handle in 'WHandle' sichern

; Text für Frage nach Filenamen ausgeben:

 LEA GetName,A1                ;Stringadresse nach A1
 BSR OutPut                    ;String ausgeben

; Filenamen eingeben:

 MOVE.L CmdBuf,D2
 MOVE.L WHandle,D1
 MOVE.L #256,D3                ;maximal 256 Zeichen eingeben
 LINKSYS Read,DosBase
 MOVE.L D0,CmdLen              ;wirkliche Eingabelänge in
                               ;'CmdLen' sichern

; CR durch NULL ersetzen

 MOVE.L CmdBuf,A0
 MOVE.B #0,-1(A0,D0)

; Lock des Files:

 MOVE.L CmdBuf,D1
 MOVE.L #-2,D2                 ;Modus lesen
 LINKSYS Lock,DosBase
 TST.L D0                      ;Lock = 0 ,dann File nicht
 BEQ EXITM                     ;vorhanden und Ende

; FileInfoBlock des Files lesen:

 MOVE.L D0,OldLock          ;sicherheitshalber alten Lock sichern
 MOVE.L D0,D1
 MOVE.L FIB,D2
 LINKSYS Examine,DosBase
 TST.L D0                      ;wenn D0 = 0 ,dann Fehler
 BEQ EXIT0

; Filetyp untersuchen:

 MOVE.L FIB,A0
 ADD.L #4,A0
 MOVE.L (A0),D0
 TST.L D0
 BPL EXIT0                     ;D0 > 0 , dann File = Directory

; Filelänge feststellen und entsprechenden Speicher reservieren:

 MOVE.L FIB,A0
 ADD.L #124,A0
 MOVE.L (A0),D0
 MOVE.L D0,PrgLen
 MOVE.L #(MEMF_PUBLIC|MEMF_CLEAR),D1
 LINKSYS AllocMem,ExecBase
 TST.L D0                      ;D0 = 0 ,kein Speicher mehr, Ende
 BEQ EXIT0
 MOVE.L D0,PrgBuf          ;Adresse des Blocks in 'PrgBuf' sichern

; File öffnen:

 MOVE.L CmdBuf,D1
 MOVE.L #MODE_OLD,D2
 LINKSYS Open,DosBase
 MOVE.L D0,OldHandle           ;Handle in 'OldHandle' sichern

; Puffer für Filenamen mit Extension reservieren:

 MOVE.L CmdLen,D0
 ADD.L #4,D0
 MOVE.L #(MEMF_PUBLIC|MEMF_CLEAR),D1
 LINKSYS AllocMem,ExecBase
 TST.L D0
 BEQ EXIT1
 MOVE.L D0,CBuf                ;Adresse in 'CBuf' sichern

; Filenamen nach CBuf kopieren und Extension anhängen:

 MOVE.L CmdLen,D0
 SUB.L #2,D0
 MOVE.L CmdBuf,A0
 MOVE.L CBuf,A1
CopyLoop:
 MOVE.B (A0)+,(A1)+
 DBRA D0,CopyLoop

 MOVE.L #XT,A0
 MOVE.L #4,D0
XTCopy:
 MOVE.B (A0)+,(A1)+
 DBRA D0,XTCopy

; neues File erzeugen:

 MOVE.L CBuf,D1
 MOVE.L #MODE_NEW,D2
 LINKSYS Open,DosBase
 TST.L D0
 BEQ EXIT2
 MOVE.L D0,NewHandle           ;FileHandle in 'NewHandle' sichern

; altes File in Programmpuffer lesen:

 MOVE.L OldHandle,D1
 MOVE.L PrgBuf,D2
 MOVE.L PrgLen,D3
 LINKSYS Read,DosBase

; nach 'CON:' oder 'RAW:' suchen:

 CLR.L D0
 MOVE.L PrgLen,D1
 MOVE.L PrgBuf,A0
 MOVE.L 0(A0,D0),D2

SearchForCon:
 CMP.L #'con:',D2
 BEQ ConFound
 CMP.L #'CON:',D2
 BEQ ConFound
 CMP.L #'raw:',D2
 BEQ ConFound
 CMP.L #'RAW:',D2
 BEQ ConFound
 LSL.L #8,D2                   ;Ein Byte weiter im Puffer nach
 ADD.L #1,D0                   ;CON:/RAW: suchen
 MOVE.B 0(A0,D0.L),D2
 CMP.L D1,D0
 BLE SearchForCon

; nichts gefunden:

NF:
 MOVE.W DELF,D0                ;prüfen, ob irgendwas verändert
 TST.W D0
 BEQ WrtToDsk                  ;ja, neues File auf Disk schreiben
 LEA NotModified,A1          ;nein, String 'NotModified' ausgeben
 BSR OutPut
 BRA NMEnde

; etwas gefunden:

ConFound:
 MOVEM.L D0-D2/A0,-(SP)        ;wichtige Register sichern
 LEA Found,A1                  ;Text ausgeben
 BSR OutPut

; wie lang ist der gefundene CON:/RAW:-Name:

 MOVEM.L (SP)+,D0-D2/A0
 MOVEM.L D0-D2/A0,-(SP)
 ADD.L D0,A0
 SUB.L #3,A0
 CLR.L D4
 MOVEQ #4,D3

SearchForNull:
 MOVE.B 0(A0,D3.L),D4
 CMP #$20,D4
 BLT PrintCon                  ;Ende wenn ASCII-Code < $20
 ADD.L #1,D3
 BRA SearchForNull

; gefundenen CON:/RAW:-Windownamen ausgeben:

PrintCon:
 MOVEM.L D3/A0,-(SP)

 MOVE.L WHandle,D1
 MOVE.L A0,D2
 LINKSYS Write,DosBase

; CR ausgeben

 LEA CR,A1
 BSR OutPut

; Fragetext, ob Ändern ausgeben:

 LEA Ndern,A1
 BSR OutPut

; Eingabe von einem Buchstaben:

WND:
 MOVEQ #2,D3
 MOVE.L CmdBuf,D2
 MOVE.L WHandle,D1
 LINKSYS Read,DosBase
 MOVE.L CmdBuf,A0
 MOVE.B (A0),D0
 CMP.B #'n',D0                 ;wenn ein 'n' oder 'N' eingegeben
 BEQ Weiter                    ;dann weitermachen
 CMP.B #'N',D0
 BEQ Weiter

; Änderungsflag setzen:

 CLR.W D0
 MOVE.W D0,DELF

; CR ausgeben:

 LEA CR,A1
 BSR OutPut

; maximale Länge der Eingabe ausgeben:

 MOVEM.L (SP)+,D3/A0
 MOVEM.L D3/A0,-(SP)

 MOVE.L D3,D0
 SUBQ #4,D0

; D0 in Dezimalzahl umwandeln

 LEA Out+11,A0                 ;Out = Ausgabepuffer
 CLR.L D1
 CLR.L D2
 CLR.L D4
 MOVE.W D0,D2         ;LowWord von D0 nach D2 und HighWord nach D3
 CLR.W D0               ;damit auch 32 Bit Zahlen ausgegeben
 MOVE.L D0,D3                  ;werden können

Loop:
 CLR.L D5
 DIVU #10,D2                   ;LowWord durch 10 teilen
 SWAP D2
 MOVE.W D2,D4                  ;Rest nach D4
 CLR.W D2
 SWAP D2
 DIVU #10,D3                   ;HighWord durch 10 teilen
 SWAP D3
 MOVE.W D3,D5                  ;Rest nach D5
 CLR.W D3
 SWAP D3
 ADD D4,D5                     ;Restwerte addieren
 ADD D1,D5              ;Übertrag aus letzter Addition addieren
 DIVU #10,D5                   ;Ergebnis durch 10 teilen
 MOVE.B D5,D1                ;Zahl > 10 , dann Übertrag (nach D1)
 SWAP D5
 ADD #$30,D5                   ;ASCII Zeichen aus Zahl machen
 MOVE.B D5,-(A0)               ;nach Out -1
 TST.W D2                      ;D2 = 0, dann
 BEQ Test                      ;nach Test
 BRA Loop                      ;weiter !!
Test:
 TST.W D3                      ;D3 auch 0
 BNE Loop                      ;wenn nicht, WEITER
 TST.W D1        ;wenn D3 auch 0, ENDE und testen ob noch Übertrag
 BEQ Print                     ;Nein, dann Ausgabe der Zahl
 ADD #$30,D1                   ;Übertrag ist die letzte Stelle
 MOVE.B D1,-(A0)               ;nach Out -1

; Ausgabe des Puffers Out:

Print:
 MOVEQ.L #32,D3                ;Länge = 32 Zeichen
 MOVE.L #Out,D2
 MOVE.L WHandle,D1
 LINKSYS Write,DosBase

; neues CON:/RAW:-Argument eingeben:

 MOVEM.L (SP)+,D3/A0           ;gesicherte Register holen
 MOVEM.L D3/A0,-(SP)
 SUBQ #4,D3                    ;CON: oder RAW: wird
 ADD.L #4,A0                   ;besser nicht verändert, nur
 MOVE.L A0,D2                  ;Argumente eingeben
 MOVE.L WHandle,D1
 LINKSYS Read,DosBase
 MOVEM.L (SP)+,D3/A0
 MOVEM.L D3/A0,-(SP)

; CR durch NULL ersetzen:

 CLR D1
 MOVE.B D1,3(A0,D0)

; nach weitern CON:/RAW:'s suchen:

Weiter:
 MOVEM.L (SP)+,D3/A0
 MOVEM.L (SP)+,D0-D2/A0
 LSL.L #8,D2
 ADD.L #1,D0
 MOVE.B 0(A0,D0.L),D2
 CMP.L D1,D0
 BLE SearchForCon
 BRA NF

; neues File auf Disk schreiben:

WrtToDsk:
 MOVE.L NewHandle,D1
 MOVE.L PrgBuf,D2
 MOVE.L PrgLen,D3
 LINKSYS Write,DosBase

NMEnde:
 LEA EndText,A1
 BSR OutPut

; warten bis RETURN gedrückt:

WTD:
 MOVE.L WHandle,D1
 MOVE.L #$ffffffff,D2
 LINKSYS WaitForChar,DosBase

 MOVE #119,D0
 CMP.B $BFEC01,D0
 BNE WTD

; File schließen:

EXIT3:
 MOVE.L NewHandle,D1
 LINKSYS Close,DosBase

 MOVE.W DELF,D0                ;Änderungsflag prüfen
 TST.W D0
 BEQ EXIT2

 MOVE.L CBuf,D1                ;nichts geändert, dann neues
 LINKSYS DeleteFile,DosBase    ;File wieder löschen

; Speicher für Namenspuffer freigeben:

EXIT2:
 MOVE.L CBuf,A1
 MOVE.L CmdLen,D0
 ADD.L #5,D0
 LINKSYS FreeMem,ExecBase

; Speicher für File wieder zurückgeben:

EXIT1:
 MOVE.L PrgBuf,A1
 MOVE.L PrgLen,D0
 LINKSYS FreeMem,ExecBase

; altes File schließen

 MOVE.L OldHandle,D1
 LINKSYS Close,DosBase

; Lock wieder freigeben:

EXIT0:
 MOVE.L OldLock,D1
 LINKSYS UnLock,DosBase

; Speicher für CmdBuf und FIB freigeben:

EXITM:
 MOVE.L CmdBuf,A1
 MOVE.L #516,D0
 LINKSYS FreeMem,ExecBase

; Window schließen:

EXIT:
 MOVE.L WHandle,D1
 LINKSYS Close,DosBase

; Dos-Library schließen:

 MOVE.L DosBase,D0
 BEQ.S No_Intui
 MOVE.L D0,A1
 CALLSYS CloseLibrary
No_Intui:
 EXIT_AMIGA

; String (Pointer in A1) ausgeben:

OutPut:
 CLR.L D3                      ;Stringlänge in ersten zwei
 MOVE.W (A1),D3                ;Bytes des Strings
 ADD.L #2,A1
 MOVE.L A1,D2
 MOVE.L WHandle,D1
 LINKSYS Write,DosBase

 RTS

; Datenbereiche:

 DATA
DosName:    DC.B 'dos.library',0
XT:         DC.B '.CR',0
GetName:    DC.B 0,18,$0a,'Name des Files : '
Found:      DC.B 0,32,$0c,$0a,'CON: / RAW: Window gefunden:',$0a
            DC.B $0a
NotModified:DC.B 0,34,$0c,$0a,$0a,$0a,$0a,'File wurde nicht '
            DC.B 'verändert !',$0a
WName:      DC.B 'CON:120/40/300/120/CRF by R.Englert © 1988',0

 ALIGN
EndText:    DC.B 0,30,$0a,$0a,$0a,$0a,'<RETURN> drücken für ENDE'
            DC.B $0a
Ndern:      DC.B 0,16,$0a,'Ändern ? (J/N) '
Out:        DC.B 'Maximal     Zeichen eingeben :',$0a,$0a
CR:         DC.B 0,1,$0a,0
DELF:       DC.W $FFFF

 ALIGN

 BSS
DosBase:    DS.L 1
CmdLen:     DS.L 1
OldHandle:  DS.L 1
NewHandle:  DS.L 1
CBuf:       DS.L 1
PrgLen:     DS.L 1
PrgBuf:     DS.L 1
OldLock:    DS.L 1
WHandle:    DS.L 1
CmdBuf:     DS.L 1
FIB:        DS.L 1
 END

