* sorry, comments only german.
* see docs for details
* © Patrick Kursawe 1994

* assemblieren mit a68k und blink
* Das GUI zum JukeBox-Programmieren ! (JukeBox © by Franz-Josef Reichert)
* Eingabe durch t:toc (Format: Titel,0,Titel,...,0)
* Ausgabe in t:jb.tracks (Format: Track,10,Track,10...)


	include exec/memory.i
	include dos/dos.i
	include exec/lists.i
	include exec/nodes.i
	include intuition/intuition.i
	include libraries/gadtools.i
	include libraries_lib.i		* Einsprünge, geändert. Für Standard-Includes _LVO Davor!
st
	move.l 4,a6
	lea iname,a1
	move.l #37,d0
	jsr OpenLibrary(a6)
	move.l d0,ibase
	beq closelibs
	lea dname,a1
	move.l #37,d0
	jsr OpenLibrary(a6)
	move.l d0,dbase
	beq closelibs
	lea gadtoolsname,a1
	move.l #37,d0
	jsr OpenLibrary(a6)
	move.l d0,gadtoolsbase
	beq closelibs
	jsr PrepareLists
	cmp.l #1,d0
	bne closelibs
	move.l ibase,a6
	lea newwin,a0
	jsr OpenWindow(a6)
	move.l d0,window
	beq closelibs
	move.l d0,a0
	move.l wd_WScreen(a0),a0
	move.l gadtoolsbase,a6
	sub.l a1,a1
	jsr GetVisualInfoA(a6)
	move.l d0,vi
	beq closewin
	lea list1,a0
	move.l d0,gng_VisualInfo(a0)
	lea list2,a0
	move.l d0,gng_VisualInfo(a0)
* Koordinaten korregieren
	move.l window,a0
	lea list1,a1
	clr.l d0
	move.b wd_BorderTop(a0),d0
	add.w #20,d0
	move.w d0,gng_TopEdge(a1)
	move.l #100,d0
	sub.w gng_TopEdge(a1),d0
	move.w d0,gng_Height(a1)
* soll reichen, jetzt Gadgets erstellen und einbinden		
	lea glistptr,a0
	jsr CreateContext(a6)
	move.l d0,context
	beq closewin
	move.l #LISTVIEW_KIND,d0
	move.l context,a0
	lea list1,a1
	lea ggtags1,a2
	jsr CreateGadgetA(a6)
	tst.l d0
	beq closewin
	move.l d0,a0
	move.l d0,gg1ptr
	move.l #LISTVIEW_KIND,d0
	lea list2,a1
	lea ggtags2,a2
	jsr CreateGadgetA(a6)
	tst.l d0
	beq closewin
	move.l d0,gg2ptr
	move.l ibase,a6
	move.l window,a0
	move.l glistptr,a1
	move.l #0,a2
	move.l #0,d0
	move.l #-1,d1
	jsr AddGList(a6)
	move.l gadtoolsbase,a6
	move.l window,a0
	move.l #0,a1
	jsr GT_RefreshWindow(a6)
	move.l ibase,a6
	move.l glistptr,a0
	move.l window,a1
	move.l #0,a2
	jsr RefreshGadgets(a6)
	move.l window,a0
	move.l wd_UserPort(a0),d7
waitport
	move.l 4,a6
	move.l d7,a0
	jsr WaitPort(a6)
	move.l d7,a0
	move.l gadtoolsbase,a6
	jsr GT_GetIMsg(a6)
	tst.l d0
	beq waitport
	move.l d0,a1
	move.l im_Class(a1),class
	move.w im_Code(a1),code
	move.l im_IAddress(a1),address
	move.l class,d0
	and.l #IDCMP_GADGETUP,d0
	tst.l d0
	beq zurück
	clr.l d0
	move.w code,d0
	move.l d0,num
zurück
	jsr GT_ReplyIMsg(a6)
	cmp.l #IDCMP_CLOSEWINDOW,class
	beq ende_der_eingabe
	move.l class,d0
	and.l #IDCMP_GADGETUP,d0
	tst.l d0
	beq weiterparsen
	move.l address,a0
	clr.l d0
	move.w gg_GadgetID(a0),d0
	move.l num,d1
	jsr Program
weiterparsen
	bra waitport
ende_der_eingabe
	jsr Rettet_Die_Eingaben
	jsr freememlist1
closewin
	move.l ibase,a6
	move.l window,a0
	jsr CloseWindow(a6)
	move.l gadtoolsbase,a6
	move.l glistptr,a0
	jsr FreeGadgets(a6)
	move.l vi,a0
	jsr FreeVisualInfo(a6)
closelibs
	move.l 4,a6
	move.l ibase,a1
	jsr CloseLibrary(a6)
	move.l dbase,a1
	jsr CloseLibrary(a6)
	move.l gadtoolsbase,a1
	jsr CloseLibrary(a6)
	move.l rec,d0
	rts

*** die listnodes aus Textdatei erstellen und eintragen ***
PrepareLists
	move.l #0,preperr
	move.l dbase,a6
	move.l #DOS_FIB,d1
	clr.l d2
	jsr AllocDosObject(a6)
	move.l d0,fib
	beq ex_no_fib
	move.l #inputname,d1
	move.l #MODE_OLDFILE,d2
	jsr Open(a6)
	move.l d0,inputhandle
	bne InputOpen
	move.l #2,preperr
	bra freefib
InputOpen
	move.l d0,d1
	move.l fib,d2
	jsr ExamineFH(a6)
	move.l fib,a0
	move.l fib_Size(a0),d0
	move.l d0,inputlen
	move.l #MEMF_CLEAR,d1
	move.l 4,a6
	jsr AllocVec(a6)
	move.l d0,filebuffer
	bne HabInBuffer
	move.l #2,preperr
	bra CloseInput
HabInBuffer
	move.l dbase,a6
	move.l inputhandle,d1
	move.l filebuffer,d2
	move.l inputlen,d3
	jsr Read(a6)

CloseInput
	move.l dbase,a6
	move.l inputhandle,d1
	jsr Close(a6)
freefib
	move.l dbase,a6
	move.l fib,d2
	move.l #DOS_FIB,d1
	jsr FreeDosObject(a6)	
	cmp.l #2,preperr
	beq freememlist1
	lea list1header,a5
	move.l filebuffer,a4
	move.l 4,a6	
	move.l #LN_SIZE,d0
	move.l #MEMF_CLEAR,d1
	jsr AllocVec(a6)
	move.l d0,LH_HEAD(a5)
	beq freememlist1
	move.l filebuffer,d7
	add.l inputlen,d7
* d7: Position für Dateiende
* a4: Aktuelle Position in Datei
* a5: aktuelle ListNode

	move.l d0,a5
	move.l a4,LN_NAME(a5)
makenodes
	cmp.l a4,d7
	bls Liste1Fertig
	cmp.b #0,(a4)+
	beq nexttext
	bra makenodes
nexttext
	move.l #LN_SIZE,d0
	move.l #MEMF_CLEAR,d1
	jsr AllocVec(a6)
	move.l d0,LN_SUCC(a5)
	beq freememlist1
	move.l a5,d1 
* Jetzt alte Node in d1
	move.l d0,a5
* neue in a5
	move.l d1,LN_PRED(a5)
	move.l a4,LN_NAME(a5)
	bra makenodes
Liste1Fertig
	move.l a5,lastentry
	lea list1header,a0
	move.l a5,LH_TAILPRED(a0)
	move.l #1,d0
	rts

freememlist1
* FileBuffer und komplette Liste freigeben
	move.l 4,a6
	move.l filebuffer,a1
	jsr FreeVec(a6)
	lea list1header,a0
letzter
	move.l lastentry,a5
letzterloop
	cmp.l #0,a5
	beq liste2checken
	move.l a5,a1
	move.l LN_PRED(a5),a5
	jsr FreeVec(a6)
	bra letzterloop
liste2checken
	move.l last2entry,a5
clear2loop
	cmp.l #0,a5
	beq ex_no_fib
	move.l a5,a1
	move.l LN_PRED(a5),a5
	jsr FreeVec(a6)
	bra clear2loop
ex_no_fib
	move.l preperr,d0
	rts
Rettet_Die_Eingaben
	move.l dbase,a6
	move.l #outputname,d1
	move.l #MODE_NEWFILE,d2
	jsr Open(a6)
	tst.l d0
	beq nixzuretten
	move.l d0,d7
	lea list2header,a5
	move.l LH_HEAD(a5),a5
rausloop
	cmp.l #0,a5
	beq ausgabezu
	clr.l d0
	move.b LN_PRI(a5),d0
	tst.l d0
	beq ausgabezu
	move.l d7,d1
	move.w d0,char
	move.l #char,d3
	move.l #format,d2
	jsr VFPrintf(a6)
	cmp.l #-1,d0
	beq ausgabezu
	move.l LN_SUCC(a5),a5
	bra rausloop 
ausgabezu
	move.l d7,d1
	jsr Close(a6)
nixzuretten
	rts
Program
	clr.l d6
	cmp.l #1,d0
	beq Zufügen
	cmp.l #2,d0
	beq entfernen
	rts
Zufügen
	move.l #1,d6
	move.l d1,d0
	lea list1header,a0
	jsr FindNodeNum
	cmp.l #0,a0
	beq progfertig
	move.l a0,a5
	move.l 4,a6
	move.l #LN_SIZE,d0
	move.l #MEMF_CLEAR,d1
	jsr AllocVec(a6)
	tst.l d0
	beq progfertig
	move.l num,d1
	addq.l #1,d1
** Titelnummer
	cmp.l #0,last2entry
	beq istdererstezumzufügen
	move.l last2entry,a0
	move.l d0,LN_SUCC(a0)
	move.l d0,a1
	move.b d1,LN_PRI(a1)
	move.l a0,LN_PRED(a1)
	move.l LN_NAME(a5),d0
	move.l d0,LN_NAME(a1)
	move.l a1,last2entry
	lea dummyentry,a0
	move.l a0,LN_SUCC(a1)
	move.l a1,LN_PRED(a0)
	bra progfertig
istdererstezumzufügen
	move.l d0,last2entry
	lea list2header,a0
	move.l d0,LH_HEAD(a0)
	move.l d0,a1
	move.b d1,LN_PRI(a1)
	move.l LN_NAME(a5),d0
	move.l d0,LN_NAME(a1)
	lea dummyentry,a0
	move.l a0,LN_SUCC(a1)
	move.l a1,LN_PRED(a0)
progfertig
	move.l gadtoolsbase,a6
	move.l gg2ptr,a0
	move.l window,a1
	sub.l a2,a2
	lea ggtags2,a3
	jsr GT_SetGadgetAttrsA(a6)
	tst.l d6
	beq novis
	move.l gg2ptr,a0
	move.l window,a1
	sub.l a2,a2
	lea vistag,a3
	jsr  GT_SetGadgetAttrsA(a6)
novis
	move.l ibase,a6
	move.l gg2ptr,a0
	move.l window,a1
	sub.l a2,a2
	jsr RefreshGadgets(a6)
	rts
entfernen
* entfernen des angeklickten Punktes aus der Liste
	move.l 4,a6
	move.l d1,d0
	lea list2header,a0
	jsr FindNodeNum
	cmp.l #0,a0
	beq progfertig
	move.l last2entry,d0
	cmp.l a0,d0
	beq warderletzte
	move.l a0,a1
	move.l LN_PRED(a1),a0
	move.l LN_SUCC(a1),a2
	cmp.l #0,a0
	beq keinpred
	move.l a2,LN_SUCC(a0)
succändern
	move.l a0,LN_PRED(a2)
	jsr FreeVec(a6)
	bra progfertig
warderletzte
	cmp.l #0,LN_PRED(a0)
	beq ganzallein
	move.l LN_PRED(a0),a1
	move.l a1,last2entry
	lea dummyentry,a2
	move.l a1,LN_PRED(a2)
	move.l a2,LN_SUCC(a1)
	move.l a0,a1
	jsr FreeVec(a6)
	bra progfertig
ganzallein
	lea dummyentry,a1
	move.l #0,LN_PRED(a1)
	lea list2header,a1
	move.l #0,LH_HEAD(a1)
	move.l #0,last2entry
	move.l a0,a1
	jsr FreeVec(a6)
	bra progfertig
keinpred
	lea list2header,a0
	move.l #0,LN_PRED(a2)
	move.l a2,LH_HEAD(a0)
	jsr FreeVec(a6)
	bra progfertig
FindNodeNum
** Diese Routine sucht die Node Nr x (ab 0)
* header in a0
* num in d0
* adresse in a0 zurück oder 0
	cmp.l #0,LH_HEAD(a0)
	beq nix
	move.l LH_HEAD(a0),a0
suchnodeloop
	cmp.l #0,d0
	beq gefunden
	move.l LN_SUCC(a0),a0
	cmp.l #0,a0
	beq gefunden
	subq.l #1,d0
	bra suchnodeloop
gefunden
	rts
nix
	clr.l d0
	rts
** Ende von FindNodeNum
ggtags1
	dc.l GTLV_Labels,list1header,TAG_DONE
ggtags2
	dc.l GTLV_Labels,list2header,TAG_DONE
vistag
	dc.l GTLV_MakeVisible
visnum
	dc.l %111111111111111,TAG_DONE   * Ganz große Numer, damit man nicht immer die höchste angeben muß!
list1header
	dc.l 0,0,0
	dc.b 0,0
list2header
	dc.l 0,0,0
	dc.b 0,0
last2entry
	dc.l 0

dummyentry
	dc.l 0,0
	dc.b 0,0
	dc.l 0
lastentry
	dc.l 0
rec
	dc.l 0
list1
	dc.w 10,30,340,75
	dc.l list1label,0
	dc.w 1
	dc.l PLACETEXT_ABOVE,0,0
list2
	dc.w 10,115,340,65
	dc.l list2label,0
	dc.w 2
	dc.l PLACETEXT_ABOVE,0,0	
newwin
	dc.w 0,10,360,190
	dc.b -1,-1
	dc.l LISTVIEWIDCMP|IDCMP_CLOSEWINDOW,WFLG_ACTIVATE|WFLG_DRAGBAR|WFLG_CLOSEGADGET|WFLG_DEPTHGADGET
	dc.l 0,0,wintitle,0,0,-1,-1
	dc.w PUBLICSCREEN
inputname
	dc.b "T:jb.toc",0
outputname
	dc.b "T:jb.tracks",0
wintitle
	dc.b "JukeBox®-Programmer ©P.Kursawe 1994",0 ; DO NOT CHANGE!
	dc.b "$VER: JukeBoxProg by Patrick Kursawe 1.0 1994",0
dname
	dc.b "dos.library",0
iname
	dc.b "intuition.library",0
gadtoolsname
	dc.b "gadtools.library",0	
list1label
	dc.b "Track auswählen",0  ;Select Track
list2label
	dc.b "Bisher gewählt",0   ;Already chosen
format
	dc.b "%d",10,0
	bss

* diese ganzen Nullen sind sicher nicht sehr elegant, aber ich wollte das Programm eigentlich
* nur schnell fertig haben. Speicher belegen und relativ adressieren kann das Ganze
* kürzer und schneller machen. bss verhindert aber das schlimmste
char
	dc.w 0
gg1ptr
	dc.l 0
gg2ptr
	dc.l 0
filebuffer
	dc.l 0
inputlen
	dc.l 0
preperr
	dc.l 0
inputhandle
	dc.l 0
outputhandle
	dc.l 0
fib
	dc.l 0
glistptr
	dc.l 0
context
	dc.l 0
vi
	dc.l 0
num
	dc.l 0
class
	dc.l 0
code
	dc.w 0
address
	dc.l 0
window
	dc.l 0
gadtoolsbase
	dc.l 0
dbase
	dc.l 0
ibase
	dc.l 0

	end
