*****************************************************
************* CoPro-Editor **************************
** Zweck: Komfortables Editieren von Dateikommen-  **
**	  taren im CLI, sowie der Protection-Flags **
**	 	  (auch von Version 1.3)           **
** Extras:	   Lademöglichkeit		   **
** Besonderheiten: Lauffähig ab Kickstart 1.2      **
** Assembler: 	   Devpac 1.2			   **
** Programmautor:  Stefan Hochmuth                 **
** (c) Kickstart 1989				   **
*****************************************************

	opt c+		Groß/klein unterscheiden
	incdir	"df0:include/"
	include	exec/memory.i
	include	libraries/dos.i
	include	intuition/intuition.i
	include	exec/exec_lib.i
	include	intuition/intuition_lib.i
	include	libraries/dos_lib.i

* Konstanten
FileNameLen	equ	50
CommentLen	equ	80
ProTextLen	equ	6
ProBoxWidth	equ	ProTextLen*8
ProBoxHeight	equ	10
ProBitCount	equ	8
StrGadgetX	equ	10
WindowWidth	equ	2*StrGadgetX+ProBoxWidth*ProBitCount
WindowHeight	equ	90
Gadget1Y	equ	25
Gadget2Y	equ	Gadget1Y+20
Gadget3Y	equ	WindowHeight-15
Gadget4Y	equ	Gadget3Y
Gadget3X	equ	20
Gadget4X	equ	WindowWidth-9*8-Gadget3X
ProBoxX		equ	StrGadgetX
ProBoxY		equ	Gadget3Y-20
Gadget_Size	equ	gg_SIZEOF-4	ohne Userdata

* Register-Konstanten *
Window		equr	A3
Memory		equr	A4
Message		equr	A5
ActualGadget	equr	Message
MyLock		equr	Message
TextAdress	equr	Message
ExecBase	equr	D4
IntBase		equr	D5
DosBase		equr	D6
GadgetNr	equr	D3
ProtectionNr	equr	GadgetNr
Error		equr	D7

* Memory-Struktur *
		rsreset
FileInfo	rs.b	fib_SIZEOF
FileName	rs.b	FileNameLen
Speicher	rs.b	0
Comment		equ	fib_Comment
Protections	equ	fib_Protection

* Makros *
CALLLIB		macro	
		jsr	_LVO\1(a6)
		endm

******** Programm **********

	movea.l	(_SysBase).w,a6
	move.l	a6,ExecBase

* Speicher für FileInfo und Benutzereingaben reservieren
	move.l	#Speicher,d0
	move.l	#MEMF_PUBLIC!MEMF_CLEAR,d1
	CALLLIB	AllocMem
	tst.l	d0
	beq.l	AllocMemErr
	movea.l	d0,Memory	

* Die Bufferzeiger in die StringGadgets eintragen
	lea	FileName(Memory),a0
	move.l	a0,StringInfo1
	lea	Comment(Memory),a0
	move.l	a0,StringInfo2

* intuition.library öffnen
	lea	intname(pc),a1
	moveq	#33,d0			ab Kickstart 1.2 wegen ActivateGadget
	CALLLIB	OpenLibrary
	move.l	d0,IntBase
	beq.l	IntOpenErr

* dos.library öffnen
	lea	dosname(pc),a1
	CALLLIB	OldOpenLibrary		jede Version
	move.l	d0,DosBase
	beq.l	DosOpenErr

* Window mit allen Gadgets öffnen
	movea.l	IntBase,a6
	lea	NewWindow(pc),a0
	CALLLIB	OpenWindow
	tst.l	d0
	beq	WindowErr	
	move.l	d0,Window

* Protectionsleiste aufbauen
	moveq	#0,d2
	bsr	ShowProtections2

	moveq	#1,GadgetNr
* Gadgets refreshen, GadgetNr eor.w 1 aktivieren
ActivateAnyGadget
	eori.w	#1,GadgetNr
	lea	Gadget1(pc),ActualGadget
	mulu	#Gadget_Size,GadgetNr
	adda.w	GadgetNr,ActualGadget	
	move.l	IntBase,a6
	lea.l	Gadget2(pc),a0
	movea.l	Window,a1
	suba.l	a2,a2
	CALLLIB	RefreshGadgets
	move.l	ActualGadget,a0	
	move.l	Window,a1
	CALLLIB	ActivateGadget

* Änderungen in der Protectionsleiste anzeigen
ShowOnlyProtections
	bsr	ShowProtections

* Auf IDCMP-Event warten
	move.l	ExecBase,a6
	move.l	wd_UserPort(Window),a0	
	CALLLIB	WaitPort

* Dann vom MessagePort abholen
	move.l	wd_UserPort(Window),a0	
	CALLLIB	GetMsg
	movea.l	d0,Message
	
* InputEvent auswerten und beantworten
	cmp.l	#CLOSEWINDOW,im_Class(Message)
	beq	Exit			wenn CloseGadget
	cmp.l	#MOUSEBUTTONS,im_Class(Message)
	bne.s	GadgetEvent
* Mausklick auswerten: wenn in die Protectionsleiste geklickt *
* wurde, dann Status des entsprechenden ProtectBits ändern *
	moveq	#0,Error
	moveq	#1,GadgetNr
	cmp.w	#SELECTDOWN,im_Code(Message)
	bne.s	ReplyIt
	move.w	im_MouseX(Message),d0
	move.w	im_MouseY(Message),d1
	cmp.w	#ProBoxY,d1
	bcs.s	ReplyIt
	cmp.w	#ProBoxY+ProBoxHeight,d1
	bhi.s	ReplyIt
	sub.w	#ProBoxX,d0
	bmi.s	ReplyIt
	cmp.w	#ProBitCount*ProBoxWidth,d0
	bhi.s	ReplyIt
	ext.l	d0
	divs	#-ProBoxWidth,d0
	addq	#ProBitCount-1,d0
	bchg.b	d0,Protections+3(Memory)
	bra.s	ReplyIt
GadgetEvent
* Wichtige Daten aus Message merken
	move.l	im_IAddress(Message),a0
	move.w	gg_GadgetID(a0),GadgetNr
* Message beantworten
ReplyIt
	movea.l	Message,a1
	CALLLIB	ReplyMsg
	cmp.w	#1,GadgetNr		wenn StringGadget
	bls	ActivateAnyGadget	dann anderes Gadget aktivieren
	move.l	DosBase,a6		für Dos-Routinen initialisiern
	move.l	StringInfo1(pc),d1	FileName für dito
	subq.w	#2,GadgetNr		drittes Gadget?
	bne.s	NichtLaden		nein, dann speichern

* Laden des Kommentars
 	moveq	#ACCESS_READ,d2
	CALLLIB	Lock			LeseLock auf Datei besorgen
	tst.l	d0
	seq.b	Error		
	beq.s	ErrorTest		
	move.l	d0,MyLock		wenn kein Fehler
	move.l	MyLock,d1
	move.l	Memory,d2
	CALLLIB	Examine			dann FileInfoBlock ausfüllen
	tst.l	d0
	seq.b	Error
	move.l	MyLock,d1
	CALLLIB	UnLock			Lock wieder freigeben
	moveq	#0,GadgetNr		Cursor auf Kommentar
	bra.s	ErrorTest

NichtLaden
* Speichern des Kommentars und der Protectionbits *
	move.l	StringInfo2(pc),d2
	CALLLIB	SetComment
	tst.l	d0
	seq.b	Error	
	beq.s	ErrorTest
	moveq	#1,GadgetNr		Cursor auf FileName
	move.l	StringInfo1(pc),d1	FileName wieder holen
	move.l	Protections(Memory),d2
	CALLLIB	SetProtection
	tst.l	d0
	seq.b	Error

* Wenn bei Diskettenoperationen ein Fehler auftrat, blinkt der Bildschirm *
ErrorTest:
	tst.b	Error
	beq.s	NoError
	move.l	IntBase,a6
	suba.l	a0,a0
	CALLLIB	DisplayBeep
	moveq	#1,GadgetNr		Cursor auf FileName
NoError
	bra	ActivateAnyGadget

* Alles Freigeben
Exit
* Window wieder schließen, Gadgets entfernen *
	movea.l	IntBase,a6
	movea.l	Window,a0
	CALLLIB	CloseWindow
* Libraries schließen *
WindowErr
	movea.l	DosBase,a1
	movea.l	ExecBase,a6	
	CALLLIB	CloseLibrary
DosOpenErr
	movea.l	IntBase,a1
	CALLLIB	CloseLibrary
IntOpenErr
* Belegten Speicher freigeben *
	movea.l	Memory,a1
	move.l	#Speicher,d0
	CALLLIB	FreeMem
AllocMemErr:
	moveq.l	#0,d0
	rts			Gleich bin ich weg!

* Protectionsleiste zeichnen *
ShowProtections
	move.l	Protections(Memory),d2	Protect-Bits aus FileInfoStruktur holen
	eori.w	#%1111,d2		LowNibble invertieren
ShowProtections2:
* Textstruktur intialisieren *
	lea	GadgetText1(pc),a2
	move.w	#ProBoxX+(ProBitCount-1)*ProBoxWidth,4(a2)
	move.w	#ProBoxY+1,6(a2)
	moveq	#ProBitCount-1,ProtectionNr
ProtectionLoop	
	lea	PText+(ProBitCount-1)*(ProTextLen+1)(pc),a0
	move.l	#$02000100,(a2)		Pen 2, RP_JAM2
	btst.b	ProtectionNr,d2
	beq.s	NoProtectionSet
	add.l	#1*(1<<24)+(RP_INVERSVID-RP_JAM2)*256,(a2)	ggf. invertieren
NoProtectionSet
	move.w	ProtectionNr,d0
	mulu	#ProTextLen+1,d0
	suba.w	d0,a0			korrekte Textadresse berechnen 
	move.l	a0,VariableTextPoi
	move.w	ProtectionNr,d0
	muls	#-ProBoxWidth,d0	X-Koordinate berechnen	
	moveq	#0,d1
	movea.l	wd_RPort(Window),a0
	movea.l	a2,a1
	movem.l	a0/d0-d1,-(sp)
	CALLLIB	PrintIText		Text ausgeben
	movem.l	(sp)+,d0-d1/a0
	lea	Border(pc),a1
	CALLLIB	DrawBorder		Border ausgeben
	dbra	ProtectionNr,ProtectionLoop	bis fertig
	rts

* Texte und Strukturen *
Title	dc.b	"CoPro-Editor 1.0 by HochiSoft in 1989",0
IText1	dc.b	"Name der Datei",0
IText2	dc.b	"Kommentartext",0
IText3	dc.b	"  Laden  ",0
IText4	dc.b	"Speichern",0
PText	dc.b	" HIDE ",0,"SCRIPT",0," PURE ",0,"ARCHI.",0
	dc.b	" READ ",0,"WRITE ",0,"EXECU.",0,"DELETE",0
intname	dc.b	"intuition.library",0
dosname	dc.b	"dos.library",0
	even
Border
	dc.w	ProBoxX+(ProBitCount-1)*ProBoxWidth,ProBoxY
	dc.b	2,0,0,5
	dc.l	XY,0

XY	dc.w	0,0,ProBoxWidth,0
	dc.w	ProBoxWidth,ProBoxHeight-1,0,ProBoxHeight-1
	dc.w	0,0

NewWindow
	dc.w	10,10,WindowWidth,WindowHeight
	dc.b	0,1
	dc.l	GADGETUP!CLOSEWINDOW!MOUSEBUTTONS
	dc.l	WINDOWDEPTH!WINDOWDRAG!WINDOWCLOSE!ACTIVATE!WINDOWACTIVE!RMBTRAP!WBENCHWINDOW
	dc.l	Gadget1,0
	dc.l	Title,0,0
	dc.w	0,0,0,0,1

Gadget1	dc.l	Gadget2
	dc.w	StrGadgetX,Gadget1Y,ProBoxWidth*ProBitCount,8
	dc.w	0,RELVERIFY,STRGADGET
	dc.l	0,0
	dc.l	GadgetText1,0,StringInfo1
	dc.w	0		= GadgetID

Gadget2	dc.l	Gadget3
	dc.w	StrGadgetX,Gadget2Y,ProBoxWidth*ProBitCount,8
	dc.w	0,RELVERIFY,STRGADGET
	dc.l	0,0
	dc.l	GadgetText2,0,StringInfo2
	dc.w	1		= GadgetID

Gadget3	dc.l	Gadget4
	dc.w	Gadget3X,Gadget3Y,9*8,8
	dc.w	GADGHBOX,RELVERIFY,BOOLGADGET
	dc.l	0,0
	dc.l	GadgetText3,0,0
	dc.w	2		= GadgetID

Gadget4	dc.l	0
	dc.w	Gadget4X,Gadget4Y,9*8,8
	dc.w	GADGHBOX,RELVERIFY,BOOLGADGET
	dc.l	0,0
	dc.l	GadgetText4,0,0
	dc.w	3		= GadgetID

StringInfo1
	dc.l	0,0
	dc.w	0,FileNameLen,1
	ds.w	5
	ds.l	3		
StringInfo2
	dc.l	0,0
	dc.w	0,CommentLen,1
	ds.w	5
	ds.l	3		
GadgetText1:	dc.b	3,0,0,0
		dc.w	0,-10
		dc.l	0
VariableTextPoi	dc.l	IText1,0

GadgetText2:	dc.b	3,0,0,0
		dc.w	0,-10
		dc.l	0,IText2,0
GadgetText3:	dc.b	1,0,RP_INVERSVID,0
		dc.w	0,0
		dc.l	0,IText3,0
GadgetText4:	dc.b	1,0,RP_INVERSVID,0
		dc.w	0,0
		dc.l	0,IText4,0

