***************************************
* 8 Channels Tracker  *****************
***************************************

Lock    = -84
UnLock  = -90
Examine = -102
ExNext  = -108
PlaneLen     = 384*640/8
MenuPlaneLen = 4*6*640/8
PattLen      = $800
TrackLen     = PattLen/8
SongLen      = PattLen*32

org  $7a000
load $7a000

p:		bsr.L	OpenLibs
		bsr.L	AllocMem
		bsr.l	SetInts
		bsr.L	RH_FOff
		bsr.L	SetAutoReq
		bsr.L	GetOldCopper
		bsr.L	BuildTables
		bsr.L	ICL
		bsr.L	PrintPattern
		lea	InitText(pc),a0
		bsr.L	PrintText
		bsr.L	PrintAll
		bsr.L	SetCursor
		move.l	#CopperList,$dff080
		bsr.s	RasterLoop
		bsr.L	StopDMA
		bsr.L	ClearAutoReq
		bsr.L	ClearInts
		bsr.L	CloseLibs
		bsr.L	FreeMem
		move.l	OldCopList(pc),$dff080
		moveq	#0,d0
		rts

* Rasterschleife **********************

RasterLoop:	bsr.s	WaitTOP
		lea	MenuExTable(pc),a0
		bsr.L	Executer
		bsr.L	EditKeyHandler
		btst	#6,$bfe001
		bne.s	RasterLoop
		btst	#2,$16(a6)
		bne.s	RasterLoop
		tst.l	MousePos
		bne.s	RasterLoop
		tst.w	AltMode
		beq.s	RasterLoop
		tst.w	ShiftMode
		beq.s	RasterLoop
		rts

* Auf letzte Ras-Pos warten ***********

WaitTOP:	move.l	$dff004,d0
		lsr.l	#8,d0
		and.w	#$1ff,d0
		cmp.w	#301,d0
		bne.s	WaitTOP
		rts

InitText:	dc.b	0,0,'Len...: $',-1
		dc.b	0,1,'RStart: $',-1
		dc.b	0,2,'REnd..: $',-1
		dc.b	0,3,'Name  :',-1
		dc.b	16,0,'Load  Sample',-1
		dc.b	16,1,'Clear Sample',-1
		dc.b	16,2,'Edit  Sample',-1
		dc.b	30,0,'load song',-1
		dc.b	30,1,'save song',-1
		dc.b	30,2,'play song',-1
		dc.b	30,3,'play patt',-1
		dc.b	41,0,'pos.:',-1
		dc.b	41,1,'patt:',-1
		dc.b	41,2,'len.:',-1
		dc.b	41,3,'speed:',-1
		dc.b	71,2,'c',-1
		dc.b	71,3,'s12345678',0
		even

* Speicher reservieren ****************

AllocMem:	move.l	4.w,a6
		move.l	#MenuPlaneLen+PlaneLen,d0
		move.l	#$10002,d1
		jsr	-198(a6)
		move.l	d0,MenuPlane
		add.l	#MenuPlaneLen,d0
		move.l	d0,Plane
		move.l	#SongLen,d0
		move.l	#$10000,d1
		jsr	-198(a6)
		move.l	d0,SongPT
		move.l	#PattLen,d0
		move.l	#$10000,d1
		jsr	-198(a6)
		move.l	d0,PatternBuffer
		move.l	#TrackLen,d0
		move.l	#$10000,d1
		jsr	-198(a6)
		move.l	d0,TrackBuffer
		rts

* Speicher freigeben ******************

FreeMem:	move.l	4.w,a6
		move.l	MenuPlane(pc),a1
		move.l	#MenuPlaneLen+PlaneLen,d0
		jsr	-210(a6)
		move.l	SongPT(pc),a1
		move.l	#SongLen,d0
		jsr	-210(a6)
		move.l	PatternBuffer(pc),a1
		move.l	#Pattlen,d0
		jsr	-210(a6)
		move.l	TrackBuffer(pc),a1
		move.l	#TrackLen,d0
		jsr	-210(a6)
		clr.w	ActSample
FM_Samples:	bsr.L	FreeSample
		addq.w	#1,ActSample
		cmp.w	#36,ActSample
		bne.s	FM_Samples
		bra.L	FreeChipSample

Plane:		dc.l	0
MenuPlane:	dc.l	0
SongPT:		dc.l	0
PatternBuffer:	dc.l	0
TrackBuffer:	dc.l	0

* Interrupts setzen *******************

SetInts:	move.l	$68.w,OldIOInt+2
		move.l	$6c.w,OldVBIInt+2
		move.l	#NewIOInt,$68.w
		move.l	#NewVBIInt,$6c.w
		bsr.L	ClearMouseMove
		bsr.L	PrintAll
		clr.l	0.w
		rts

* Auto-Request setzen *****************

SetAutoReq:	move.l	4.w,a6
		lea	IntName(pc),a1
		jsr	-408(a6)
		move.l	d0,a1
		lea	-346(a1),a2
		move.l	(a2),OldAutoReqPT+2
		move.l	#NewAutoReq,(a2)
		move.l	a2,AutoReqPT
		jmp	-414(a6)

IntName:	dc.b	'intuition.library',0

* Auto Request loeschen ***************

ClearAutoReq:	move.l	AutoReqPT(pc),a0
		move.l	OldAutoReqPT+2(pc),(a0)
		rts
AutoReqPT:	dc.l	0

* Neue Auto-Request routine ***********

NewAutoReq:	move.l	$68.w,NAR_IO
		move.l	$6c.w,NAR_VB
		move.l	OldIOInt+2(pc),$68.w
		move.l	OldVBIInt+2(pc),$6c.w
		move.l	OldCopList(pc),$dff080
OldAutoReqPT:	jsr	0
		move.l	#CopperList,$dff080
		move.l	NAR_VB(pc),$6c.w
		move.l	NAR_IO(pc),$68.w
		rts

NAR_IO:		dc.l	0
NAR_VB:		dc.l	0

* Alte Copperliste holen **************

GetOldCopper:	move.l	4.w,a6
		lea	GName(pc),a1
		jsr	-408(a6)
		move.l	d0,a1
		move.l	38(a1),OldCopList
		jmp	-414(a6)

GName:		dc.b	'graphics.library',0,0
OldCopList:	dc.l	0

* Tabellen aufbauen *******************

BuildTables:	lea	FullPeriodTab+2(pc),a0	;Noten - Stepwerte
		lea	HBuff(pc),a1
		moveq	#35,d7
BT_Loop1:	move.l	#$38c000,d0
		divu	(a0)+,d0
		and.l	#$ffff,d0
		add.l	d0,d0
		add.l	d0,d0
		move.l	d0,(a1)+
		dbf	d7,BT_Loop1
		rts

HBuff:		blk.l	36,0

* DMA aus *****************************

StopDMA:	move.w	#$f,$dff096
		clr.w	$dff0a8
		clr.w	$dff0b8
		clr.w	$dff0c8
		clr.w	$dff0d8
		rts

* Auf Laufwerke warten ****************

WaitDrives:	move.l	4.w,a6
		move.l	a6,a0
		lea	$15e(a0),a0
		lea	TrackDiskName(pc),a1
		jsr	-276(a6)
		move.l	d0,a6
		lea	$24(a6),a6
		moveq	#3,d7
WD_WaitDrive:	tst.l	(a6)+
		beq.s	WD_NextDrive
		move.l	-4(a6),a0
WD_DriveOn:	btst	#7,$41(a0)
		beq.s	WD_DriveOn
WD_NextDrive:	dbf	d7,WD_WaitDrive
		rts
TrackDiskName:	dc.b	'trackdisk.device',0,0

* Auf Blitter warten ******************

WB:		btst	#6,$dff002
		bne.s	WB
		rts

* Auf Maus warten *********************

WaitLifted:	bsr.L	WaitTOP
		btst	#6,$bfe001
		beq.s	WaitLifted
		btst	#2,$dff016
		beq.s	WaitLifted
		rts

* eingene Interrupts loeschen *********

ClearInts:	move.l	OldIOInt+2(pc),$68.w
		move.l	OldVBIInt+2(pc),$6c.w
		rts

* DOS - Lib oeffnen und schliessen ****

OpenLibs:	move.l	4.w,a6
		lea	DosName(pc),a1
		jsr	-408(a6)
		move.l	d0,DosBase
		rts
CloseLibs:	move.l	4.w,a6
		move.l	DosBase(pc),a1
		jmp	-414(a6)

DosName:	dc.b	'dos.library',0
DosBase:	dc.l	0

* Copperliste initialsieren ***********

ICL:		lea	CopperList(pc),a0
		move.l	#Sprite1,d0
		move.w	d0,6(a0)
		swap	d0
		move.w	d0,2(a0)
		lea	CopMenuPlane(pc),a0
		move.l	MenuPlane(pc),d0
		move.w	d0,6(a0)
		swap	d0
		move.w	d0,2(a0)
		move.w	CursorY(pc),d0
		bra.L	SetPlanePT

* Tastatur checken ********************

EditKeyHandler:	move.b	ActKey(pc),d0
		clr.b	ActKey
		tst.b	d0
		beq.L	EKH_Ex
		move.l	SongPT(pc),a5		;Pattpos ermitteln
		move.w	ActPattern(pc),d1	;Pattpos
		mulu	#PattLen,d1
		add.l	d1,a5
		move.l	a5,a4
		move.l	a4,a3
		move.w	CursorY(pc),d6
		move.w	d6,d1
		lsl.w	#5,d1
		add.w	d1,a5
		addq.w	#4,d6
		moveq	#0,d1			;Einsprung 1 ermitteln
		move.w	CursorX(pc),d1
		divu	#5,d1
		move.w	d1,d5
		lsr.w	#1,d5
		move.w	d5,EKH_Channel
		move.w	d1,d5
		mulu	#9,d5
		add.w	#9,d5
		add.w	d1,d1
		add.w	d1,d1
		add.w	d1,a5
		add.w	d1,a4
		swap	d1
		add.w	d1,d1
		lea	KH_Handlers(pc),a0
		move.w	(a0,d1.w),d1
		lea	p(pc),a0
		movem.l	d0/a3-a4,-(sp)
		jsr	(a0,d1.w)
		movem.l	(sp)+,d0/a3-a4
		lea	KH_NormKeys(pc),a0
		lea	KH_NormKeysJmp(pc),a1
		lea	p(pc),a2
		tst.w	ShiftMode
		beq.s	KH_NoShift
		lea	KH_ShiftKeys(pc),a0
		lea	KH_ShiftKeysJmp(pc),a1
KH_NoShift:	tst.w	AltMode
		beq.s	KH_NextKey
		lea	KH_AltKeys(pc),a0
		lea	KH_AltKeysJmp(pc),a1
KH_NextKey:	move.w	(a1)+,d2
		move.b	(a0)+,d1
		beq.s	EKH_Ex
		cmp.b	d0,d1
		bne.s	KH_NextKey
		jmp	(a2,d2.w)
EKH_Ex:		rts

KH_NormKeys:	dc.b	$10,$11,$15,$16,$17,$18,$19,$f,$e,$c,$d,0
KH_NormKeysJmp:	dc.w	SetTabs1-p,SetTabs2-p
		dc.w	SetCursor0-p,SetCursor16-p,SetCursor32-p,SetCursor48-p,SetCursor63-p
		dc.w	CursorLeft-p,CursorRight-p,CursorUp-p,CursorDown-p
KH_ShiftKeys:	dc.b	$10,$11,$12,$13,$14,0
KH_ShiftKeysJmp:dc.w	TNoteDown-p,TNoteUp-p
		dc.w	CutTrack-p,CopyTrack-p,PasteTrack-p
KH_AltKeys:	dc.b	$10,$11,$12,$13,$14,$e,$f,0
KH_AltKeysJmp:	dc.w	PNoteDown-p,PNoteUp-p
		dc.w	CutPattern-p,CopyPattern-p,PastePattern-p
		dc.w	AddPattern-p,SubPattern-p
KH_Handlers:	dc.w	KH_CheckNote-p,KH_CheckSample-p,KH_CheckEffect-p
		dc.w	KH_CheckNib1-p,KH_CheckNib2-p

* Note angeschlagen ? *****************

KH_CheckNote:	bsr.L	TestNoteKey
		bmi.s	CN_NoNote
		lea	PrintBuffer(pc),a0		;Note setzen
		move.b	d5,(a0)
		move.b	d6,1(a0)
		move.l	ActPeriodTab(pc),a1
		move.b	(a1,d0.w),d0
		bmi.L	CN_NoNote
		move.b	d0,(a5)
		clr.b	1(a5)
		tst.b	d0
		beq.L	CN_NoPlay
		move.b	ActSample+1,1(a5)
		move.w	d0,d1
		and.w	#$ff,d1
		move.w	EKH_Channel(pc),d0
		bsr.s	PlayNote
CN_NoPlay:	movem.l	d2/a0,-(sp)
		bsr.L	ClearCursor
		movem.l	(sp)+,a0/d2
		add.w	d2,d2
		add.w	d2,d2
		move.l	ActNoteTab(pc),a1
		move.l	(a1,d2.w),2(a0)
		clr.b	6(a0)
		bsr.L	PrintText
		move.w	d5,d0
		addq.w	#4,d0
		move.w	d6,d1
		move.w	ActSample(pc),d2
		tst.b	(a5)
		bne.s	CN_Seted
		moveq	#0,d2
		clr.b	1(a5)
CN_Seted:	bsr.L	Print0Z
		bra.L	CursorDown
CN_NoNote:	rts
EKH_Channel:	dc.w	0

* Note spielen ************************
* <d0:Kanal-Bit <d1:hoehe *************

PlayNote:	moveq	#0,d3
		bset	d0,d3
		move.w	d3,$dff096
		lsl.w	#4,d0
		lea	$dff0a0,a1
		add.w	d0,a1
		move.l	ActCSPT(pc),d0
		beq.s	PN_NoPlay
		move.l	d0,(a1)
		move.l	ActCSLen(pc),d0
		lsr.l	#1,d0
		beq.s	PN_NoPlay
		move.w	d0,4(a1)
		lea	FullPeriodTab(pc),a2
		add.w	d1,d1
		move.w	(a2,d1.w),6(a1)
		move.w	#64,8(a1)
		move.w	#500,d0
PN_DMAWait:	dbf	d0,PN_DMAWait
		or.w	#$8000,d3
		move.w	d3,$dff096
		move.w	#1,4(a1)
PN_NoPlay:	rts

* Samplenummer eingegeben *************

KH_CheckSample:	bsr.L	TestKey0Z
		bne.s	CS_NoSample
		move.b	d2,1(a5)
		lea	PrintBuffer(pc),a0
		addq.b	#4,d5
		move.b	d5,(a0)
		move.b	d6,1(a0)
		lea	Z0Tab(pc),a1
		move.b	(a1,d2.w),2(a0)
		clr.b	3(a0)
		move.l	a0,-(sp)
		bsr.L	ClearCursor
		move.l	(sp)+,a0
		bsr.L	PrintText
		bra.L	CursorDown
CS_NoSample:	rts

* Effect-Nummer eingegeben ************

KH_CheckEffect:	bsr.L	TestKey0Z
		bne.s	CE_NoEff
		move.b	d2,2(a5)
		lea	PrintBuffer(pc),a0
		addq.b	#5,d5
		move.b	d5,(a0)
		move.b	d6,1(a0)
		lea	Z0Tab(pc),a1
		move.b	(a1,d2.w),2(a0)
		clr.b	3(a0)
		move.l	a0,-(sp)
		bsr.L	ClearCursor
		move.l	(sp)+,a0
		bsr.L	PrintText
		bra.L	CursorDown
CE_NoEff:	rts

* Nibble 1 des Effekts-Wertes *********

KH_CheckNib1:	bsr.L	TestHex
		bne.s	CN1_NoNib
		and.b	#$0f,3(a5)
		lsl.b	#4,d2
		or.b	d2,3(a5)
		lea	PrintBuffer(pc),a0
		addq.b	#6,d5
		move.b	d5,(a0)
		move.b	d6,1(a0)
		lea	Z0Tab(pc),a1
		lsr.b	#4,d2
		move.b	(a1,d2.w),2(a0)
		clr.b	3(a0)
		move.l	a0,-(sp)
		bsr.L	ClearCursor
		move.l	(sp)+,a0
		bsr.L	PrintText
		bra.L	CursorDown
CN1_NoNib:	rts

* Nibble 2 des Effekts-Wertes *********

KH_CheckNib2:	bsr.L	TestHex
		bne.s	CN2_NoNib
		and.b	#$f0,3(a5)
		or.b	d2,3(a5)
		lea	PrintBuffer(pc),a0
		addq.b	#7,d5
		move.b	d5,(a0)
		move.b	d6,1(a0)
		lea	Z0Tab(pc),a1
		move.b	(a1,d2.w),2(a0)
		clr.b	3(a0)
		move.l	a0,-(sp)
		bsr.L	ClearCursor
		move.l	(sp)+,a0
		bsr.L	PrintText
		bra.L	CursorDown
CN2_NoNib:	rts

* Noten-Taste gedrueckt ***************

TestNoteKey:	lea	NoteKeyTab(pc),a0
		moveq	#-1,d2
TNK_Loop:	addq.w	#1,d2
		move.b	(a0)+,d1
		beq.L	TNK_NoNote
		cmp.b	d1,d0
		bne.s	TNK_Loop
		move.w	d2,d0
		rts
TNK_NoNote:	moveq	#-1,d0
		rts

* 0-z gedrueckt ? *********************

TestKey0Z:	lea	Key0ZTab(pc),a0
		moveq	#-1,d2
TRZ_Loop:	addq.w	#1,d2
		move.b	(a0)+,d1
		beq.s	TRZ_No
		cmp.b	d0,d1
		bne.s	TRZ_Loop
		moveq	#0,d0
		rts
TRZ_No:		moveq	#-1,d0
		rts
Key0ZTab:	dc.b	'0123456789abcdefghijklmnopqrstuvwxyz',0,0

* Hex gedrueckt ***********************

TestHex:	lea	HexKeyTab(pc),a0
		moveq	#-1,d2
TH_Loop:	addq.w	#1,d2
		move.b	(a0)+,d1
		beq.s	TH_No
		cmp.b	d0,d1
		bne.s	TH_Loop
		moveq	#0,d0
		rts
TH_No:		moveq	#-1,d0
		rts

HexKeyTab:	dc.b	'0123456789abcdef',0,0

* Cursor-Bewegung *********************

CursorLeft:	subq.w	#1,CursorX
		bpl.s	CL_Ok
		move.w	#39,CursorX
CL_Ok:		bra.L	SetCursor
CursorRight:	addq.w	#1,CursorX
		cmp.w	#40,CursorX
		blt.s	CR_Ok
		clr.w	CursorX
CR_Ok:		bra.L	SetCursor
CursorUp:	subq.w	#1,CursorY
		and.w	#$3f,CursorY
		bra.s	NewCursorY
CursorDown:	addq.w	#1,CursorY
		bra.s	NewCursorY
SetCursor0:	clr.w	CursorY
		bra.s	NewCursorY
SetCursor16:	move.w	#16,CursorY
		bra.s	NewCursorY
SetCursor32:	move.w	#32,CursorY
		bra.s	NewCursorY
SetCursor48:	move.w	#48,CursorY
		bra.s	NewCursorY
SetCursor63:	move.w	#63,CursorY
		bra.s	NewCursorY
NewCursorY:	and.w	#$3f,CursorY
		move.w	CursorY(pc),d0
		bsr.L	SetPlanePT
		bra.L	SetCursor

* Pattern +1 / -1 *********************

SubPattern:	moveq	#-1,d0
		bra.s	PattChanged
AddPattern:	moveq	#1,d0
PattChanged:	add.w	d0,ActPattern
		and.w	#$1f,ActPattern
		bra.L	PrintPattern

* Tabellen setzen *********************

SetTabs1:	move.l	#NoteTab1,ActNoteTab
		move.l	#PeriodTab1,ActPeriodTab
		rts
SetTabs2:	move.l	#NoteTab2,ActNoteTab
		move.l	#PeriodTab2,ActPeriodTab
		rts
ActNoteTab:	dc.l	NoteTab1
ActPeriodTab:	dc.l	PeriodTab1

* TrackBuffer handlings ***************

TNoteUp:	moveq	#63,d0
TNU_Loop:	move.b	(a4),d1
		beq.s	TNU_Next
		cmp.b	#36,d1
		beq.s	TNU_Next
		addq.b	#1,d1
		move.b	d1,(a4)
TNU_Next:	lea	32(a4),a4
		dbf	d0,TNU_Loop
		bra.l	PrintPattern
TNoteDown:	moveq	#63,d0
TND_Loop:	move.b	(a4),d1
		subq.b	#1,d1
		ble.s	TND_Next
		move.b	d1,(a4)
TND_Next:	lea	32(a4),a4
		dbf	d0,TND_Loop
		bra.l	PrintPattern
CutTrack:	move.l	TrackBuffer(pc),a0
		moveq	#63,d0
CT_Loop:	move.l	(a4),(a0)+
		clr.l	(a4)
		lea	32(a4),a4
		dbf	d0,CT_Loop
		bra.l	PrintPattern
CopyTrack:	move.l	TrackBuffer(pc),a0
		moveq	#63,d0
CoT_Loop:	move.l	(a4),(a0)+
		lea	32(a4),a4
		dbf	d0,CoT_Loop
		rts
PasteTrack:	move.l	TrackBuffer(pc),a0
		moveq	#63,d0
PT_Loop:	move.l	(a0)+,(a4)
		lea	32(a4),a4
		dbf	d0,PT_Loop
		bra.l	PrintPattern

* Pattern handlings *******************

PNoteUp:	move.w	#511,d0
PNU_Loop:	move.b	(a3),d1
		beq.s	PNU_Next
		cmp.b	#36,d1
		beq.s	PNU_Next
		addq.b	#1,d1
		move.b	d1,(a3)
PNU_Next:	addq.w	#4,a3
		dbf	d0,PNU_Loop
		bra.l	PrintPattern
PNoteDown:	move.w	#511,d0
PND_Loop:	move.b	(a3),d1
		subq.b	#1,d1
		ble.s	PND_Next
		move.b	d1,(a3)
PND_Next:	addq.w	#4,a3
		dbf	d0,PND_Loop
		bra.l	PrintPattern
CutPattern:	move.l	PatternBuffer(pc),a0
		move.w	#511,d0
CPt_Loop:	move.l	(a3),(a0)+
		clr.l	(a3)+
		dbf	d0,CPt_Loop
		bra.l	PrintPattern
CopyPattern:	move.l	PatternBuffer(pc),a0
		move.w	#511,d0
CPa_Loop:	move.l	(a3)+,(a0)+
		dbf	d0,CPa_Loop
		rts
PastePattern:	move.l	PatternBuffer(pc),a0
		move.w	#511,d0
PPp_Loop:	move.l	(a0)+,(a3)+
		dbf	d0,PPp_Loop
		bra.l	PrintPattern

***************************************
* OUTPUT ******************************
***************************************

* Alle Menu-Angaben ausgeben **********

PrintAll:	lea	PA_CLText(pc),a0
		bsr.L	PrintText
		move.w	ActSample(pc),d2	;Act Sample
		cmp.w	ActChipSample(pc),d2
		beq.s	PA_Same
		bsr.L	StopDMA
		move.w	ActSample,ActChipSample
		bsr.L	FreeChipSample
		bsr.L	AllocChipSample
PA_Same:	move.w	ActSample(pc),d2
		moveq	#5,d0
		moveq	#3,d1
		bsr.L	Print0Z
		lea	SH_Samples(pc),a0	;Sample Name
		move.w	ActSample(pc),d0
		lsl.w	#5,d0
		add.w	d0,a0
		move.l	a0,-(sp)
		moveq	#8,d0
		moveq	#3,d1
		bsr.L	PrintXY
		move.l	(sp),a0
		move.l	20(a0),d2
		moveq	#9,d0
		moveq	#0,d1
		bsr.L	PrintHex5
		move.l	(sp),a0
		move.l	24(a0),d2
		moveq	#9,d0
		moveq	#1,d1
		bsr.L	PrintHex5
		move.l	(sp)+,a0
		move.l	28(a0),d2
		moveq	#9,d0
		moveq	#2,d1
		bsr.L	PrintHex5
		moveq	#0,d2
		move.b	SH_Speed(pc),d2
		moveq	#48,d0
		moveq	#3,d1
		bsr.L	Print0Z
		moveq	#0,d2
		move.b	ActPosition(pc),d2
		moveq	#46,d0
		moveq	#0,d1
		bsr.L	PrintDez3
		lea	SH_Patterns(pc),a0
		moveq	#0,d2
		move.b	ActPosition(pc),d2
		move.b	(a0,d2.w),d2
		moveq	#47,d0
		moveq	#1,d1
		bsr.L	PrintDez2
		move.b	SH_Len(pc),d2
		moveq	#46,d0
		moveq	#2,d1
		bsr.L	Printdez3

		moveq	#72,d5
		move.b	PlayChannels(pc),d6
		moveq	#7,d7
PA_Loop1:	move.w	d5,d0
		moveq	#2,d1
		lea	ChannelStates(pc),a0
		btst	d7,d6
		bne.s	PA_ChannelOn
		addq.w	#2,a0
PA_ChannelOn:	bsr.L	PrintXY
		addq.w	#1,d5
		dbf	d7,PA_Loop1
		rts

ChannelStates:	dc.b	'*',0,'-',0

* Chip-Sample freigeben ***************

FreeChipSample:	move.l	ActCSPT(pc),d0
		beq.s	FCS_NotFree
		clr.l	ActCSPT
		move.l	d0,a1
		move.l	ActCSLen(pc),d0
		move.l	4.w,a6
		jsr	-210(a6)
FCS_NotFree:	rts

* Chip-Sample reservieren *************

AllocChipSample:lea	SampleTab(pc),a0
		move.w	ActSample(pc),d0
		lsl.w	#3,d0
		move.l	(a0,d0.w),d1
		beq.s	ACS_Ex
		move.l	d1,a4
		move.l	4(a0,d0.w),d0
		move.l	d0,ActCSLen
		moveq	#2,d1
		move.l	4.w,a6
		jsr	-198(a6)
		move.l	d0,ActCSPT
		beq.s	ACS_Ex
		move.l	d0,a1
		move.l	ActCSLen(pc),d0
		subq.l	#2,d0
		ble.s	ACS_Ex

		move.w	#$4040,(a1)+
		ble.s	ACS_Ex
ACS_Copy:	move.b	(a4)+,(a1)+
		subq.l	#1,d0
		bne.s	ACS_Copy
ACS_Ex:		rts

ActChipSample:	dc.w	-1
ActCSPT:	dc.l	0
ActCSLen:	dc.l	0

PA_CLText:	dc.b	8,3,'--------------------',0,0

* PlanePT an d0 setzen ****************

SetPlanePT:	cmp.w	#19,d0
		blt.s	SPP_First
		cmp.w	#45,d0
		bge.s	SPP_Last
		sub.w	#19,d0
		mulu	#6*80,d0
		add.l	Plane(pc),d0
		bra.s	SPP_Set
SPP_Last:	move.l	Plane(pc),d0
		add.l	#25*6*80,d0
		bra.s	SPP_Set
SPP_First:	move.l	Plane(pc),d0
SPP_Set:	lea	CopPlane(pc),a1
		move.w	d0,6(a1)
		swap	d0
		move.w	d0,2(a1)
		rts

* Pattern ausgeben ********************

PrintPattern:	clr.w	BplCon
		bsr.L	ClearCursor
		bsr.L	ClearPlane
		moveq	#0,d0
		move.w	ActPattern(pc),d0
		mulu	#PattLen,d0
		add.l	SongPT(pc),d0
		move.l	d0,a5
		lea	FullNoteTab(pc),a4
		moveq	#4,d1
PP_YLoop:	moveq	#0,d0
		move.w	d1,-(sp)
		move.w	ActPattern(pc),d2
		bsr.L	PrintDez2
		move.w	(sp),d1
		moveq	#3,d0
		move.w	d1,d2
		subq.w	#4,d2
		bsr.L	PrintDez2
		move.w	(sp),d1
		moveq	#6,d0
		move.w	d1,d2
		subq.w	#4,d2
		bsr.L	PrintHex2
		moveq	#9,d0
		move.w	(sp)+,d1
PP_XLoop:	movem.w	d0-d1,-(sp)
		move.b	(a5)+,d2
		add.w	d2,d2
		add.w	d2,d2
		lea	PrintBuffer(pc),a0
		move.l	a0,a1
		move.b	d0,(a0)+
		move.b	d1,(a0)+
		move.l	(a4,d2.w),(a0)+
		clr.b	(a0)+
		move.l	a1,a0
		bsr.L	PrintText
		movem.w	(sp)+,d0-d1
		addq.w	#4,d0
		movem.w	d0-d1,-(sp)
		move.b	(a5)+,d2
		bsr.s	Print0Z
		movem.w	(sp)+,d0-d1
		addq.w	#1,d0
		movem.w	d0-d1,-(sp)
		move.b	(a5)+,d2
		bsr.s	Print0Z
		movem.w	(sp)+,d0-d1
		addq.w	#1,d0
		movem.w	d0-d1,-(sp)
		move.b	(a5)+,d2
		bsr.s	PrintHex2
		movem.w	(sp)+,d0-d1
		add.w	#3,d0
		cmp.w	#80,d0
		blt.s	PP_XLoop
		addq.w	#1,d1
		cmp.w	#64+4,d1
		bne.L	PP_YLoop
		bsr.L	SetCursor
		move.w	#$9200,BplCon
		rts

ActPattern:	dc.w	0

* SpezialZahl 0-z ausgeben ************

Print0Z:	bsr.s	P0Z_Set
		bra.L	PrintText
P0Z_Set:	lea	PrintBuffer(pc),a0
		move.b	d0,(a0)
		move.b	d1,1(a0)
		lea	Z0Tab(pc),a1
		move.b	(a1,d2.w),d2
		move.b	d2,2(a0)
		clr.b	3(a0)
		rts

* Hex d2 an d0/d1 ausgeben ************

PrintHex2:	bsr.s	PH_Init
		bra.s	PH_2
PrintHex4:	bsr.s	PH_Init
		bra.s	PH_4
PrintHex5:	bsr.s	PH_Init
		move.l	d2,d1
		swap	d1
		bsr.s	PH_AddHex
PH_4:		move.w	d2,d1
		rol.w	#4,d1
		bsr.s	PH_AddHex
		move.w	d2,d1
		lsr.w	#8,d1
		bsr.s	PH_AddHex
PH_2:		move.w	d2,d1
		lsr.w	#4,d1
		bsr.s	PH_AddHex
		move.w	d2,d1
		bsr.s	PH_AddHex
		lea	PrintBuffer(pc),a0
		bra.s	PrintText

PH_Init:	lea	PrintBuffer(pc),a0
		lea	Z0Tab(pc),a1
		clr.l	(a0)
		clr.l	4(a0)
		move.b	d0,(a0)+
		move.b	d1,(a0)+
		rts

PH_AddHex:	and.w	#$f,d1
		move.b	(a1,d1.w),(a0)+
		rts

PrintBuffer:	dc.l	0,0

* Dez d2 an d0/d1 ausgeben ************

PrintDez3:	lea	PD_3(pc),a0
		lea	PrintBuffer(pc),a1
		move.l	#'000'*256,2(a1)
		bra.s	PrintDez
PrintDez2:	lea	PD_2(pc),a0
		lea	PrintBuffer(pc),a1
		move.w	#'00',2(a1)
		clr.b	4(a1)
		bra.s	PrintDez
PrintDez:	move.b	d0,(a1)+
		move.b	d1,(a1)+
PD_NextStell:	move.w	(a0)+,d3
		beq.s	PD_Ready
PD_Loop:	sub.w	d3,d2
		bpl.s	PD_AddDez
		add.w	d3,d2
		addq.w	#1,a1
		bra.s	PD_NextStell
PD_AddDez:	addq.b	#1,(a1)
		bra.s	PD_Loop
PD_Ready:	lea	PrintBuffer(pc),a0
		bra.s	PrintText
PD_3:		dc.w	100
PD_2:		dc.w	10,1,0

* Text a0 ausgeben ********************
* 0=End -1=weiter *********************

PrintText:	moveq	#0,d0
		moveq	#0,d1
		move.b	(a0)+,d0
		move.b	(a0)+,d1
PrintXY:	move.l	MenuPlane(pc),a2
		lea	Chars,a3
		add.w	d0,a2
		mulu	#6*80,d1
		add.w	d1,a2
		moveq	#96,d1
		moveq	#32,d2
PT_CharLoop:	moveq	#0,d0
		move.b	(a0)+,d0
		beq.s	PT_Ready
		bmi.s	PrintText
		cmp.b	d1,d0
		blt.s	PT_Big
		sub.b	d2,d0
PT_Big:		sub.b	d2,d0
		lea	(a3,d0.w),a1
		move.b	(a1),(a2)
		move.b	64(a1),80(a2)
		move.b	64*2(a1),80*2(a2)
		move.b	64*3(a1),80*3(a2)
		move.b	64*4(a1),80*4(a2)
		addq.w	#1,a2
		bra.s	PT_CharLoop
PT_Ready:	rts

* Plane loeschen **********************

ClearPlane:	move.l	Plane(pc),a0
		moveq	#0,d0
		moveq	#0,d1
		moveq	#0,d2
		moveq	#0,d3
		moveq	#0,d4
		move.w	#$180-1,d5
CP_Loop:	movem.l	d0-d4,(a0)
		lea	20(a0),a0
		movem.l	d0-d4,(a0)
		lea	20(a0),a0
		movem.l	d0-d4,(a0)
		lea	20(a0),a0
		movem.l	d0-d4,(a0)
		lea	20(a0),a0
		dbf	d5,CP_Loop
		rts

* Cursor neu setzen *******************

SetCursor:	movem.w	CursorX(pc),d0-d1
		addq.w	#4,d1
		lea	CursorTab(pc),a0
		move.b	(a0,d0.w),d0
SetCursorXY:	movem.w	d0-d1,-(sp)
		bsr.s	ClearCursor
		movem.w	(sp)+,d0-d1
		movem.w	d0-d1,OldCPos
InvertCursor:	move.l	MenuPlane(pc),a0
		mulu	#6*80,d1
		add.w	d1,a0
		add.w	d0,a0
		moveq	#4,d0
IC_Loop:	not.b	(a0)
		lea	80(a0),a0
		dbf	d0,IC_Loop
		rts

ClearCursor:	tst.l	OldCPos
		bmi.s	CC_Cleared
		movem.w	OldCPos(pc),d0-d1
		bsr.s	InvertCursor
		moveq	#-1,d0
		move.l	d0,OldCPos
CC_Cleared:	rts

OldCPos:	dc.l	-1
CursorX:	dc.w	0	;\
CursorY:	dc.w	0	;/

***************************************
* INTERRUPT ***************************
***************************************

* neuer Vertical-Blank interrupt ******

NewVBIInt:	movem.l	d0-d7/a0-a6,-(sp)
		bsr.L	KeyRepHandler
		bsr.L	ControlMouse
		movem.l	(sp)+,d0-d7/a0-a6
OldVBIInt:	jmp	0

* neuer IO Interrupt ******************

NewIOInt:	movem.l	d0-d2/a0,-(sp)
		move.b	$bfed01,d0
		bclr	#7,d0
		bclr	#3,d0
		beq.L	NII_Ex
		moveq	#0,d2
		move.b	$bfec01,d2
		bset	#6,$bfee01
		not.b	d2
		ror.b	#1,d2
		moveq	#60,d1
NII_Wait:	dbf	d1,NII_Wait
		bclr	#6,$bfee01
		tst.b	d2
		bmi.s	NII_ExtraKeys
		cmp.b	#$40,d2
		blt.s	NII_NormKeys
		bgt.s	NII_ExtraKeys
		move.b	#' ',ActKey		;Leerzeichen =$40
		bra.s	NII_NewKey
NII_ExtraKeys:	cmp.b	#$65,d2
		beq.L	NII_AltOn1
		cmp.b	#$e5,d2
		beq.L	NII_AltOff1
		cmp.b	#$64,d2
		beq.L	NII_AltOn2
		cmp.b	#$e4,d2
		beq.L	NII_AltOff2
		cmp.b	#$61,d2
		beq.L	NII_ShiftOn1
		cmp.b	#$e1,d2
		beq.L	NII_ShiftOff1
		cmp.b	#$60,d2
		beq.L	NII_ShiftOn2
		cmp.b	#$e0,d2
		beq.L	NII_ShiftOff2
		btst	#7,d2
		bne.s	NII_StopRep
		sub.b	#$40,d2			;Extra-Zeichen >$40
		cmp.b	#$20,d2
		bge.s	NII_StopRep
		move.b	d2,ActKey
		bra.s	NII_NewKey
NII_NormKeys:	lea	RawNormTab(pc),a0	;Normal-Zeichen <$40
		tst.w	ShiftMode
		beq.s	NII_NoShift
		lea	RawShiftTab(pc),a0
NII_NoShift:	move.b	(a0,d2.w),ActKey
NII_NewKey:	move.w	#10,RepCounter
		move.b	ActKey(pc),OldKey
		bra.s	NII_Ex
NII_StopRep:	clr.w	RepCounter
NII_Ex:		move.l	4.w,a0
		move.l	120(a0),a0
		move.l	(a0),a0
		move.l	14(a0),a0
		or.b	d0,41(a0)
		movem.l	(sp)+,d0-d2/a0
OldIOInt:	jmp	0
KeyRepHandler:	tst.w	RepCounter
		beq.s	KRH_Noo
		subq.w	#1,RepCounter
		bne.s	KRH_Noo
		move.w	#2,RepCounter
		move.b	OldKey(pc),ActKey
KRH_Noo:	rts
NII_AltOn1:	bset	#0,AltMode
		bra.s	NII_Ex
NII_AltOff1:	bclr	#0,AltMode
		bra.s	NII_Ex
NII_AltOn2:	bset	#1,AltMode
		bra.s	NII_Ex
NII_AltOff2:	bclr	#1,AltMode
		bra.s	NII_Ex
NII_ShiftOn1:	bset	#0,ShiftMode
		bra.s	NII_Ex
NII_ShiftOff1:	bclr	#0,ShiftMode
		bra.s	NII_Ex
NII_ShiftOn2:	bset	#1,ShiftMode
		bra.L	NII_Ex
NII_ShiftOff2:	bclr	#1,ShiftMode
		bra.L	NII_Ex
RawNormTab:	dc.b	'`1234567890-=\ 0'
		dc.b	'qwertyuiop[] 123'
		dc.b	"asdfghjkl;'  456"
		dc.b	'<zxcvbnm,./ .789'
RawShiftTab:	dc.b	'~!@#$%^&*()_+| 0'
		dc.b	'qwertyuiop{} 123'
		dc.b	'asdfghjkl:"  456'
		dc.b	'>zxcvbnm<>? .789'
ActKey:		dc.w	0
OldKey:		dc.w	0
AltMode:	dc.w	0
ShiftMode:	dc.w	0
RepCounter:	dc.w	0

* Mauspositionen ermitteln+setzen *****

ControlMouse:	movem.w	MousePos(pc),d0-d1
		move.w	$dff00a,d2
		clr.w	$dff036
		move.w	d2,d3
		sub.w	OldLoPos(pc),d2
		and.w	#$303,d3
		move.w	d3,OldLoPos
		move.w	d2,d3
		lsr.w	#8,d3
		ext.w	d2
		ext.w	d3
		add.w	d2,d0
		add.w	d3,d1
CM_NoChange:	tst.w	d0
		bpl.s	CM_X1
		moveq	#0,d0
CM_X1:		tst.w	d1
		bpl.s	CM_Y1
		moveq	#0,d1
CM_Y1:		cmp.w	#639,d0
		blt.s	CM_x2
		move.w	#639,d0
CM_x2:		cmp.w	#514,d1
		blt.s	CM_y2
		move.w	#514,d1
CM_y2:		movem.w	d0-d1,MousePos
		lsr.w	#1,d0
		lsr.w	#1,d1
		lea	Sprite1,a0
		moveq	#5,d3
SetSprite:	add.w	#128,d0
		add.w	#$2b,d1
		move.w	d1,d2
		add.w	d3,d2
		moveq	#0,d3
		move.b	d0,d3		;Horiz Lo
		ror.l	#1,d3		;Vert End Hi
		ror.w	#8,d2
		move.b	d2,d3
		ror.l	#1,d3		;Vert Start Hi
		ror.w	#8,d1
		move.b	d1,d3
		and.b	#1,d3
		ror.l	#6,d3		;Vert End Lo
		rol.w	#8,d2
		move.b	d2,d3
		ror.l	#8,d3		;Horiz Start Hi
		lsr.w	#1,d0
		move.b	d0,d3
		ror.l	#8,d3		;Vert Start Lo
		rol.w	#8,d1
		move.b	d1,d3
		ror.l	#8,d3
		move.l	d3,(a0)
		rts

* MausMove auf 0 **********************

ClearMouseMove:	clr.w	$dff036
		move.w	$dff00a,OldLoPos
		rts

MousePos:	dc.l	0
OldLoPos:	dc.w	0
Sprite1:	dc.l	0
		dc.l	$0000F000,$6000A000,$7000D000,$3800A800,$10001000
		dc.l	0

***************************************
* MENUES ******************************
***************************************

* AusfuehrungsPRG <a0: Ex Struct ******

Executer:	move.l	a0,a5
		movem.w	MousePos(pc),d0-d1
		moveq	#0,d2
		btst	#6,$bfe001
		seq	d2
		add.w	d2,d2
		btst	#2,$dff016
		seq	d2
		tst.w	d2
		beq.s	E_NotPushed
		move.b	d2,E_RightFlag
		bsr.s	E_RenderTest
		move.l	(a5),d0
		beq.s	EM_Ex
		tst.w	4(a5)
		bne.s	EM_DecRep
		move.w	#4,4(a5)
		move.l	d0,a0
		bsr.L	InvRender
		move.l	(a5),a0
		move.l	-(a0),d0
		beq.s	E_MLeft
		move.l	d0,a1
		tst.w	E_RightFlag
		bne.s	E_MRight
E_MLeft:	move.l	-(a0),a1
E_MRight:	move.l	a5,-(sp)
		jsr	(a1)
		move.l	(sp)+,a5
		move.l	(a5),a0
		bra.L	InvRender
EM_DecRep:	subq.w	#1,4(a5)
EM_Ex:		rts
E_RightFlag:	dc.w	0
E_NotPushed:	clr.w	4(a5)
E_RenderTest:	lsr.w	#3,d0
		divu	#12,d1
		bsr.s	E_TestIn
		bne.s	E_NotIn
		cmp.l	(a5),a0
		beq.s	ERT_Ex
		move.l	(a5),a1
		move.l	a0,(a5)
		move.l	a1,a0
		move.l	a0,d0
		beq.s	E_NoOldRender
		bsr.L	InvRender
E_NoOldRender:	move.l	(a5),a0
		bra.L	InvRender
E_NotIn:	move.l	(a5),d0
		beq.s	ERT_Ex
		clr.l	(a5)
		move.l	d0,a0
		bra.s	InvRender
ERT_Ex:		rts
E_TestIn:	lea	6(a5),a0
E_TILoop:	move.l	(a0)+,a1
		move.l	a1,d2
		beq.s	E_Neg
		addq.w	#4,a0
		cmp.w	(a0),d0
		blt.s	E_Next
		cmp.w	2(a0),d1
		blt.s	E_Next
		cmp.w	4(a0),d0
		bgt.s	E_Next
		cmp.w	6(a0),d1
		bgt.s	E_Next
		moveq	#0,d0
		rts
E_Next:		addq.w	#8,a0
		bra.s	E_TILoop
E_Neg:		moveq	#-1,d0
		rts

* Rand a0 invertieren *****************

InvRenders:	tst.w	(a0)
		bmi.s	IR_Ex
		bsr.s	InvRender
		addq.w	#8,a0
		bra.s	InvRenders
IR_Ex:		rts
InvRender:	move.l	a0,d0
		beq.L	MR_Ready
		movem.w	(a0),d0-d3
		move.l	MenuPlane(pc),a3
		mulu	#6*80,d1
		add.w	d0,d1
		move.w	d1,d5
		lea	-80(a3,d5.w),a1
		tst.w	2(a0)
		beq.s	MR_NoTOP
MR_TOP:		not.b	(a1)+
		cmp.w	d0,d2
		beq.s	MR_NoTOP
		addq.w	#1,d0
		bra.s	MR_TOP
MR_NoTOP:	movem.w	(a0),d0-d3
		tst.w	d0
		beq.s	MR_LeftReady
		lea	-1(a3,d5.w),a1
		moveq	#1,d4
		tst.w	d1
		beq.s	MR_Left
		eor.b	d4,-80(a1)
MR_Left:	eor.b	d4,(a1)
		eor.b	d4,80(a1)
		eor.b	d4,80*2(a1)
		eor.b	d4,80*3(a1)
		eor.b	d4,80*4(a1)
		eor.b	d4,80*5(a1)
		cmp.w	d1,d3
		beq.s	MR_LeftReady
		lea	80*6(a1),a1
		addq.w	#1,d1
		bra.s	MR_Left
MR_LeftReady:	movem.w	(a0),d0-d3
		lea	(a3,d5.w),a1
		sub.w	d0,d2
		add.w	d2,a1
		moveq	#-128,d4
		cmp.w	#79,4(a0)
		beq.s	MR_RightReady
		tst.w	d1
		beq.s	MR_Right
		eor.b	d4,-79(a1)
MR_Right:	eor.b	d4,1(a1)
		eor.b	d4,80+1(a1)
		eor.b	d4,80*2+1(a1)
		eor.b	d4,80*3+1(a1)
		eor.b	d4,80*4+1(a1)
		eor.b	d4,80*5+1(a1)
		cmp.w	d1,d3
		beq.s	MR_RightReady
		lea	80*6(a1),a1
		addq.w	#1,d1
		bra.s	MR_Right
MR_RightReady:	movem.w	(a0),d0-d3
		mulu	#6*80,d3
		lea	(a3,d3.w),a1
		lea	5*80(a1),a1
		add.w	d0,a1
MR_Down:	not.b	(a1)+
		cmp.w	d0,d2
		beq.s	MR_Ready
		addq.w	#1,d0
		bra.s	MR_Down
MR_Ready:	rts

MenuExTable:	dc.l	0
		dc.w	0
		dc.l	LoadSample,0
		dc.w	16,0,27,0
		dc.l	ClearSample,0
		dc.w	16,1,27,1
		dc.l	EditSample,0
		dc.w	16,2,27,2
		dc.l	LoadSong,0
		dc.w	30,0,38,0
		dc.l	SaveSong,0
		dc.w	30,1,38,1
		dc.l	PlaySong,0
		dc.w	30,2,38,2
		dc.l	PlayPattern,0
		dc.w	30,3,38,3
		dc.l	AddSample,SubSample
		dc.w	0,3,27,3
		dc.l	AddPos,SubPos
		dc.w	41,0,48,0
		dc.l	AddActPos,SubActPos
		dc.w	41,1,48,1
		dc.l	AddLen,SubLen
		dc.w	41,2,48,2
		dc.l	AddSpeed,SubSpeed
		dc.w	41,3,48,3

		dc.l	SwAllOn,SwAllOff
		dc.w	71,2,71,3
		dc.l	SwChannel1,0
		dc.w	72,2,72,3
		dc.l	SwChannel2,0
		dc.w	73,2,73,3
		dc.l	SwChannel3,0
		dc.w	74,2,74,3
		dc.l	SwChannel4,0
		dc.w	75,2,75,3
		dc.l	SwChannel5,0
		dc.w	76,2,76,3
		dc.l	SwChannel6,0
		dc.w	77,2,77,3
		dc.l	SwChannel7,0
		dc.w	78,2,78,3
		dc.l	SwChannel8,0
		dc.w	79,2,79,3
		dc.l	0

***************************************
* SONGS *******************************
***************************************

* Song laden **************************

LoadSong:	lea	LoadSongText(pc),a0
		bsr.L	FileSystem
		tst.l	d0
		ble.s	LS_Ex
		move.l	#FullFileText,FileName
		bsr.L	OpenFile
		beq.s	LS_Ex
		move.l	#SongHeader,FileBuffer
		move.l	#SongHeaderEnd-SongHeader,FileLen
		bsr.L	LoadFilePart
		bsr.L	GetHighestP
		mulu	#PattLen,d0
		move.l	d0,FileLen
		move.l	SongPT(pc),FileBuffer
		bsr.s	LoadFilePart
		lea	SongHeader(pc),a5
		moveq	#0,d7
LS_LoadSamples:	move.l	20(a5),d0
		move.l	d0,FileLen
		move.w	d7,ActSample
		bsr.L	AllocSample
		beq.s	LS_Next
		move.l	d0,FileBuffer
		bsr.s	LoadFilePart
LS_Next:	lea	32(a5),a5
		addq.w	#1,d7
		cmp.w	#36,d7
		bne.s	LS_LoadSamples
		clr.w	ActSample
		bsr.L	CloseFile
		bsr.L	PrintPattern
LS_Ex:		move.w	#-1,ActChipSample
		bra.L	PrintAll

LoadSongText:	dc.b	'Load Song',0

* File zum lesen oeffnen **************

OpenFile:	move.l	FileName(pc),d1
		move.l	#1005,d2
		move.l	DosBase(pc),a6
		jsr	-30(a6)
		move.l	d0,FileHandle
		rts

* Fileteil laden **********************

LoadFilePart:	move.l	FileHandle(pc),d1
		move.l	FileBuffer(pc),d2
		move.l	FileLen(pc),d3
		move.l	DosBase(pc),a6
		jmp	-42(a6)

* Song speichern **********************

SaveSong:	lea	SaveSongText(pc),a0
		bsr.L	FileSystem
		tst.l	d0
		bmi.s	SS_Ex
		move.l	#FullFileText,FileName
		bsr.L	OpenSFile
		beq.s	SS_Ex
		move.l	#SongHeader,FileBuffer
		move.l	#SongHeaderEnd-SongHeader,FileLen
		bsr.L	SaveFilePart
		bsr.s	GetHighestP
		mulu	#PattLen,d0
		move.l	d0,FileLen
		move.l	SongPT(pc),FileBuffer
		bsr.s	SaveFilePart

		moveq	#35,d7
		lea	SH_Samples(pc),a4
		lea	SampleTab(pc),a5
SS_SaveSamples:	move.l	(a5),d0
		beq.s	SS_Next
		move.l	20(a4),d1
		beq.s	SS_Next
		move.l	d0,FileBuffer
		move.l	d1,FileLen
		bsr.s	SaveFilePart
SS_Next:	lea	32(a4),a4
		lea	8(a5),a5
		dbf	d7,SS_SaveSamples
		bsr.s	CloseFile
SS_Ex:		rts

SaveSongText:	dc.b	'Save Song',0


* Hoechste PatternNummer + 1 ermitteln*

GetHighestP:	lea	SH_Patterns(pc),a0
		moveq	#0,d1
		moveq	#0,d0
		moveq	#127,d2
GHP_Loop:	move.b	(a0)+,d1
		cmp.w	d1,d0
		bgt.s	GHP_Cont
		move.w	d1,d0
GHP_Cont:	dbf	d2,GHP_Loop
		addq.w	#1,d0
		rts

* File zum schreiben oeffnen **********

OpenSFile:	move.l	FileName(pc),d1
		move.l	#1006,d2
		move.l	DosBase(pc),a6
		jsr	-30(a6)
		move.l	d0,FileHandle
		rts

* Teil eines Files speichern **********

SaveFilePart:	move.l	FileHandle(pc),d1
		move.l	FileBuffer(pc),d2
		move.l	FileLen(pc),d3
		move.l	DosBase(pc),a6
		jmp	-48(a6)

* File schliessen *********************

CloseFile:	move.l	FileHandle(pc),d1
		move.l	DosBase(pc),a6
		jmp	-36(a6)

FileHandle:	dc.l	0

***************************************
* SAMPLES *****************************
***************************************

* Act Sample laden ********************

LoadSample:	lea	LoadSampleText(pc),a0
		bsr.L	FileSystem
		tst.l	d0
		ble.L	LSa_Ex
		bsr.L	AllocSample
		beq.L	LSa_Ex
		move.l	d0,FileBuffer
		move.l	d1,FileLen
		move.l	#FullFileText,FileName
		lea	FileText(pc),a0
		lea	SH_Samples(pc),a1
		move.w	ActSample(pc),d0
		lsl.w	#5,d0
		add.w	d0,a1
		moveq	#19,d0
LS_NewName:	move.b	(a0)+,(a1)+
		dbf	d0,LS_NewName
		move.l	d1,(a1)+
		clr.l	(a1)+
		clr.l	(a1)+
		bsr.L	LoadFile
		move.l	FileBuffer(pc),a0
		move.l	FileLen(pc),d0
		move.b	#$80,d2
LS_7Bit:	move.b	(a0),d1
		eor.b	d2,d1
		lsr.b	#1,d1
		move.b	d1,(a0)+
		subq.l	#1,d0
		bne.s	LS_7Bit
LSa_Ex:		move.w	#-1,ActChipSample
		bra.L	PrintAll
LoadSampleText:	dc.b	'Load Sample',0

* Sample loeschen *********************

ClearSample:	bsr.s	FreeSample
		lea	SH_Samples(pc),a0
		move.w	ActSample(pc),d0
		lsl.w	#5,d0
		add.w	d0,a0
		moveq	#7,d0
CS_Loop:	clr.l	(a0)+		
		dbf	d0,CS_Loop
		bra.L	PrintAll

* ActSample+1 *************************

AddSample:	cmp.w	#35,ActSample
		beq.s	AS_Ex
		addq.w	#1,ActSample
AS_Ex:		bra.L	PrintAll

* Act Sample-1 ************************

SubSample:	tst.w	ActSample
		beq.L	SSa_Ex
		subq.w	#1,ActSample
SSa_Ex:		bra.L	PrintAll

* Act Sample freigeben ****************

FreeSample:	lea	SampleTab(pc),a0
		move.w	ActSample(pc),d0
		lsl.w	#3,d0
		add.w	d0,a0
		tst.l	(a0)
		beq.s	FS_Ready
		move.l	(a0),a1
		clr.l	(a0)+
		move.l	(a0),d0
		clr.l	(a0)+
		move.l	4.w,a6
		jsr	-210(a6)
FS_Ready:	rts

* Act Sample reservieren **************

AllocSample:	move.l	d0,-(sp)
		bsr.s	FreeSample
		move.l	(sp),d0
		move.l	#$10000,d1
		move.l	4.w,a6
		jsr	-198(a6)
		tst.l	d0
		beq.s	AS_End
		lea	SampleTab(pc),a0
		move.w	ActSample(pc),d1
		lsl.w	#3,d1
		add.w	d1,a0
		move.l	d0,(a0)+
		move.l	(sp),d1
		move.l	d1,(a0)+
AS_End:		move.l	(sp)+,d1
		tst.l	d0
		rts

ActSample:	dc.w	0
SampleTab:	blk.l	[36*2],0

* File laden **************************

LoadFile:	move.l	FileName(pc),d1
		move.l	#1005,d2
		move.l	DosBase(pc),a6
		jsr	-30(a6)
		move.l	d0,d7
		beq.s	LF_Ex
		move.l	d7,d1
		move.l	FileBuffer(pc),d2
		move.l	FileLen(pc),d3
		jsr	-42(a6)
		move.l	d7,d1
		jsr	-36(a6)
LF_Ex:		rts

FileName:	dc.l	0
FileBuffer:	dc.l	0
FileLen:	dc.l	0

* Speed + 1 ***************************

AddSpeed:	cmp.b	#$f,SH_Speed
		beq.s	AS_NoAdd
		addq.b	#1,SH_Speed
AS_NoAdd:	bra.L	PrintAll

* Speed - 1 ***************************

SubSpeed:	cmp.b	#1,SH_Speed
		beq.s	SS_NoSub
		subq.b	#1,SH_Speed
SS_NoSub:	bra.L	PrintAll

* Pos +1 ******************************

AddPos:		move.b	SH_Len(pc),d0
		subq.b	#1,d0
		cmp.b	ActPosition(pc),d0
		beq.s	AP_Ex
		cmp.b	#127,ActPosition
		beq.s	AP_Ex
		addq.b	#1,ActPosition
		bra.L	PrintAll
AP_Ex:		rts

* Pos -1 ******************************

SubPos:		tst.b	ActPosition
		beq.s	SP_Ex
		subq.b	#1,ActPosition
		bra.L	PrintAll
SP_Ex:		rts

* Add Position +1 **********************

AddActPos:	lea	SH_Patterns(pc),a0
		moveq	#0,d0
		move.b	ActPosition(pc),d0
		cmp.b	#31,(a0,d0.w)
		beq.s	AAP_Ex
		addq.b	#1,(a0,d0.w)
		bra.L	PrintAll
AAP_Ex:		rts

* Sub Position -1 **********************

SubActPos:	lea	SH_Patterns(pc),a0
		moveq	#0,d0
		move.b	ActPosition(pc),d0
		tst.b	(a0,d0.w)
		beq.s	SAP_Ex
		subq.b	#1,(a0,d0.w)
		bra.L	PrintAll
SAP_Ex:		rts
ActPosition:	dc.w	0

* Len -1 ******************************

SubLen:		cmp.b	#1,SH_Len
		beq.s	SL_Ex
		subq.b	#1,SH_Len
		move.b	ActPosition(pc),d0
		cmp.b	SH_Len(pc),d0
		bne.L	PrintAll
		subq.b	#1,ActPosition
		bra.L	PrintAll
SL_Ex:		rts

* Len +1 ******************************

AddLen:		cmp.b	#128,SH_Len
		beq.s	AL_Ex
		addq.b	#1,SH_Len
		bra.L	PrintAll
AL_Ex:		rts

* Kanaele - ein - ausschalten *********

SwAllOn:	st	PlayChannels
		bra.L	PrintAll
SwAllOff:	sf	PlayChannels
		bra.L	PrintAll
SwChannel1:	moveq	#7,d0
		bra.s	SwChannel
SwChannel2:	moveq	#6,d0
		bra.s	SwChannel
SwChannel3:	moveq	#5,d0
		bra.s	SwChannel
SwChannel4:	moveq	#4,d0
		bra.s	SwChannel
SwChannel5:	moveq	#3,d0
		bra.s	SwChannel
SwChannel6:	moveq	#2,d0
		bra.s	SwChannel
SwChannel7:	moveq	#1,d0
		bra.s	SwChannel
SwChannel8:	moveq	#0,d0
SwChannel:	bchg	d0,PlayChannels
		bra.L	PrintAll
PlayChannels:	dc.w	-1

***************************************
* Play-Routinen ***********************
***************************************

GetTrkPos:	tst.w	SongMode
		beq.s	GTP_Patt
		move.w	ActPointer(pc),-(sp)
		move.w	(sp),d2
		moveq	#46,d0
		moveq	#0,d1
		bsr.L	PrintDez3
		lea	SH_Patterns(pc),a0
		move.w	(sp)+,d2
		move.b	(a0,d2.w),d2
		move.w	d2,-(sp)
		moveq	#47,d0
		moveq	#1,d1
		bsr.L	PrintDez2
		move.w	(sp)+,d0
		bra.s	GTP_Ok
GTP_Patt:	move.w	ActPointer(pc),d0
GTP_Ok:		move.l	SongPT(pc),a0
		mulu	#PattLen,d0
		add.l	d0,a0
		move.l	a0,TrkPos
		clr.w	PattY
		rts
SongMode:	dc.w	0
ActPointer:	dc.w	0
PlaySong:	move.w	#1,SongMode
		move.b	ActPosition(pc),ActPointer+1
		bra.s	PlayIt
PlayPattern:	clr.w	SongMode
		move.w	ActPattern(pc),ActPointer
PlayIt:		bsr.l	WaitDrives
		move.w	#$4000,$dff09a
		bsr.L	WaitLifted
		bsr.L	ClearBuffs
		move.b	#$40,0.w
		bsr.L	GetTrkPos
		subq.w	#1,PattY
		sub.l	#32,TrkPos
		move.b	SH_Speed(pc),ActSpeed
		clr.w	ActCyC
		move.w	#$f,$dff096
		move.l	#CBuff0,$dff0a0
		move.l	#CBuff1,$dff0b0
		move.l	#CBuff2,$dff0c0
		move.l	#CBuff3,$dff0d0
		move.w	#313,d0
		move.w	d0,$dff0a4
		move.w	d0,$dff0b4
		move.w	d0,$dff0c4
		move.w	d0,$dff0d4
		move.w	#227,d0
		move.w	d0,$dff0a6
		move.w	d0,$dff0b6
		move.w	d0,$dff0c6
		move.w	d0,$dff0d6
		moveq	#64,d0
		move.w	d0,$dff0a8
		move.w	d0,$dff0b8
		move.w	d0,$dff0c8
		move.w	d0,$dff0d8
		bsr.L	WaitTOP
		moveq	#9,d0
PP_Wait2:	dbf	d0,PP_Wait2
		move.w	#$800f,$dff096
PP_Loop:	bsr.L	ReplayHandler
		lea	PBuffs(pc),a2
		movem.l	(a2),a3-a4
		lea	CBuff0+313(pc),a5
		bsr.L	BuildBuff
		addq.w	#8,a2
		movem.l	(a2),a3-a4
		lea	CBuff1+313(pc),a5
		bsr.L	BuildBuff
		addq.w	#8,a2
		movem.l	(a2),a3-a4
		lea	CBuff2+313(pc),a5
		bsr.L	BuildBuff
		addq.w	#8,a2
		movem.l	(a2),a3-a4
		lea	CBuff3+313(pc),a5
		bsr.L	BuildBuff
		bsr.L	ReplayHandler
		lea	PBuffs(pc),a2
		movem.l	(a2),a3-a4
		lea	CBuff0(pc),a5
		bsr.s	BuildBuff
		addq.w	#8,a2
		movem.l	(a2),a3-a4
		lea	CBuff1(pc),a5
		bsr.s	BuildBuff
		addq.w	#8,a2
		movem.l	(a2),a3-a4
		lea	CBuff2(pc),a5
		bsr.s	BuildBuff
		addq.w	#8,a2
		movem.l	(a2),a3-a4
		lea	CBuff3(pc),a5
		bsr.s	BuildBuff
		btst	#6,$bfe001
		bne.L	PP_Loop
		move.w	#$f,$dff096
		clr.w	$dff0a8
		clr.w	$dff0b8
		clr.w	$dff0c8
		clr.w	$dff0d8
		bsr.L	InvertLine
		move.w	CursorY(pc),d0
		bsr.L	SetPlanePT
		bsr.L	PrintAll
		bsr.L	WaitLifted
		bsr.L	ClearMouseMove
		move.w	#$c000,$dff09a
		rts

* Buffer aufbauen *********************


GetSample:	macro
		move.b	(a0,d0.w),d4
		add.b	(a1,d1.w),d4
		eor.b	d5,d4
		move.b	d4,(a5)+
		swap	d0
		swap	d1
		add.l	d2,d0
		add.l	d3,d1
		swap	d0
		swap	d1
		endm


BuildBuff:	move.l	8(a3),d0
		move.l	8(a4),d1
		asr.l	#3,d0
		asr.l	#3,d1
		muls	#313,d0
		muls	#313,d1
		lsl.l	#3,d0
		lsl.l	#3,d1
		swap	d0
		swap	d1
		ext.l	d0
		ext.l	d1
		move.l	4(a3),d2
		move.l	4(a4),d3
		tst.l	8(a3)
		bpl.s	BB_Ch1NRev
		exg	d0,d2
BB_Ch1NRev:	tst.l	8(a4)
		bpl.s	BB_Ch2NRev
		exg	d1,d3
BB_Ch2NRev:	cmp.l	d2,d0
		blt.s	BB_CH1Ok
		clr.l	(a3)
		clr.l	4(a3)
		clr.l	8(a3)
		tst.l	12(a3)
		beq.s	BB_Ch1Ok
		lea	12(a3),a3
		add.l	#12,(a2)
BB_CH1Ok:	cmp.l	d3,d1
		blt.s	BB_CH2Ok
		clr.l	(a4)
		clr.l	4(a4)
		clr.l	8(a4)
		tst.l	12(a4)
		beq.s	BB_Ch2Ok
		lea	12(a4),a4
		add.l	#12,4(a2)
BB_CH2Ok:	move.l	(a3),a0
		move.l	8(a3),d2
		move.l	(a4),a1
		move.l	8(a4),d3
		moveq	#0,d0
		moveq	#0,d1
		moveq	#9,d7
		moveq	#-128,d5
		move.w	#$f0f,$dff180
BB_Loop:	GetSample
		GetSample
		GetSample
		GetSample
		GetSample
		GetSample
		GetSample
		GetSample
		GetSample
		GetSample
		GetSample
		GetSample
		GetSample
		GetSample
		GetSample
		GetSample
		GetSample
		GetSample
		GetSample
		GetSample
		GetSample
		GetSample
		GetSample
		GetSample
		GetSample
		GetSample
		GetSample
		GetSample
		GetSample
		GetSample
		dbf	d7,BB_Loop
		moveq	#1,d7
BB_Loop2:	GetSample
		GetSample
		GetSample
		GetSample
		GetSample
		GetSample
		dbf	d7,BB_Loop2
		GetSample
		clr.w	$dff180
		ext.l	d0
		ext.l	d1
		add.l	d0,a0
		add.l	d1,a1
		move.l	a0,(a3)
		move.l	a1,(a4)
		sub.l	d0,4(a3)
		sub.l	d1,4(a4)
		rts

* ReplayHandler ***********************

ReplayHandler:	bsr.L	WaitTOP
		tst.w	ActCyc
		bne.s	RH_Effects
		bsr.s	RH
RH_Effects:	subq.w	#1,ActCyc

		move.l	TrkPos(pc),a2
		lea	PBuffs(pc),a5
		moveq	#7,d7
RH_EffLoop:	move.l	(a5)+,a0
		move.b	2(a2),d0
		moveq	#0,d1
		move.b	3(a2),d1
		cmp.b	#30,d0
		bne.s	RH_NoSlideUp
		bsr.s	RH_SlideUp
RH_NoSlideUp:	cmp.b	#13,d0
		bne.s	RH_NoSlideDown
		bsr.s	RH_SlideDown
RH_NoSlideDown:	addq.w	#4,a2
		dbf	d7,RH_EffLoop
		rts
RH_SlideUp:	tst.l	8(a0)
		bmi.s	RH_SlideDownD
RH_SlideUpD:	lsl.w	#4,d1
		add.l	d1,8(a0)
		rts
RH_SlideDown:	tst.l	8(a0)
		bmi.s	RH_SlideUpD
RH_SlideDownD:	lsl.w	#4,d1
		sub.l	d1,8(a0)
		rts
RH:		move.b	ActSpeed(pc),ActCyc+1
		add.l	#32,TrkPos
		bsr.L	InvertLine
		addq.w	#1,PattY
		cmp.w	#64,PattY
		bne.s	RH_NoNewS
		clr.w	PattY
		sub.l	#64*32,TrkPos
		tst.w	SongMode
		beq.s	RH_NoNewS
		addq.w	#1,ActPointer
		move.w	ActPointer(pc),d0
		cmp.b	SH_Len(pc),d0
		bne.s	RH_NextPos
		clr.w	ActPointer
		move.b	SH_Speed(pc),ActSpeed
RH_NextPos:	bsr.L	GetTrkPos
RH_NoNewS:	bsr.L	InvertLine
		lea	SampleTab(pc),a0
		lea	SH_Samples(pc),a1
		move.l	TrkPos(pc),a2
		lea	PBuff0(pc),a3
		lea	HBuff(pc),a4
		lea	PBuffs(pc),a5
		move.b	PlayChannels(pc),d6
		moveq	#7,d7
RH_Loop:	btst	d7,d6
		beq.s	RH_NoAction
		moveq	#0,d0
		move.b	(a2),d0
		beq.s	RH_Cont
		move.l	a3,(a5)
		subq.w	#1,d0
		add.w	d0,d0
		add.w	d0,d0
		move.l	(a4,d0.w),8(a3)
		moveq	#0,d0
		move.b	1(a2),d0
		lsl.w	#3,d0
		move.l	(a0,d0.w),(a3)
		add.w	d0,d0
		add.w	d0,d0
		move.l	20(a1,d0.w),4(a3)
		clr.l	12(a3)
		clr.l	16(a3)
		clr.l	20(a3)
		move.b	2(a2),d0
		move.b	3(a2),d1
		cmp.b	#27,d0
		bne.s	RH_Cont
		bsr.s	RH_Reverse
RH_Cont:	move.b	2(a2),d0
		move.b	3(a2),d1
		cmp.b	#28,d0
		bne.s	RH_NoSpeed
		bsr.s	RH_Speed
RH_NoSpeed:	cmp.b	#15,d0
		bne.s	RH_NoFilter
		bsr.s	RH_Filter
RH_NoFilter:
RH_NoAction:	addq.w	#4,a2
		lea	28(a3),a3
		addq.w	#4,a5
		dbf	d7,RH_Loop
		rts

* Speed aendern ***********************

RH_Speed:	tst.b	d1
		beq.s	RH_SEx
		and.b	#$F,D1
		move.b	d1,ActSpeed
		move.b	d1,ActCyc+1
RH_SEx:		rts
ActSpeed:	dc.w	0

* Filter an/aus ***********************

RH_Filter:	tst.b	d1
		beq.s	RH_FOff
		bclr	#1,$bfe001
		rts
RH_FOff:	bset	#1,$bfe001
		rts

* (R)everse abspielen *****************
* (00):NormRev (01):Norm+Rev **********
* (02)Rev+Norm ************************

RH_Reverse:	tst.b	d1
		bne.s	RH_R01
		neg.l	8(a3)
		move.l	4(a3),d0
		subq.l	#1,d0
		add.l	d0,(a3)
		neg.l	4(a3)
		rts
RH_R01:		cmp.b	#1,d1
		bne.s	RH_R02
		movem.l	(a3),d0-d2
		neg.l	d2
		subq.l	#1,d1
		add.l	d1,d0
		neg.l	d1
		movem.l	d0-d2,12(a3)
		rts
RH_R02:		cmp.b	#2,d1
		bne.s	RH_RNot
		movem.l	(a3),d0-d2
		movem.l	d0-d2,12(a3)
		neg.l	d2
		subq.l	#1,d1
		add.l	d1,d0
		neg.l	d1
		movem.l	d0-d2,(a3)
RH_RNot:	rts

* C+PBuffs loeschen *******************

ClearBuffs:	lea	CBuff0(pc),a0
		moveq	#0,d1
		move.w	#312,d0
CB_Loop:	move.l	d1,(a0)+
		move.l	d1,(a0)+
		dbf	d0,CB_Loop
		lea	PBuff0(pc),a0
		moveq	#7*8-1,d0
CB_Loop2:	clr.l	(a0)+
		dbf	d0,CB_Loop2
		lea	PBuffs(pc),a1
		lea	PBuff0(pc),a0
		moveq	#7,d0
CB_Loop3:	move.l	a0,(a1)+
		lea	28(a0),a0
		dbf	d0,CB_Loop3
		rts

* Line invertieren ********************

InvertLine:	tst.w	SongMode
		bne.s	IL_Ex
		tst.w	PattY
		bmi.s	IL_Ex
		move.l	#$090f0000,$dff040
		moveq	#-1,d0
		move.l	d0,$dff044
		clr.l	$dff064
		move.l	Plane(pc),a0
		move.w	PattY(pc),d0
		mulu	#6*80,d0
		add.w	d0,a0
		move.l	a0,$dff050
		move.l	a0,$dff054
		move.w	#5*64+40,$dff058
		move.w	PattY(pc),d0
		bsr.L	SetPlanePT
		bra.L	WB
IL_Ex:		rts

ActCyc:		dc.w	0
TrkPos:		dc.l	0
PattY:		dc.w	0

CBuff0:		blk.w	313,0
CBuff1:		blk.w	313,0
CBuff2:		blk.w	313,0
CBuff3:		blk.w	313,0

PBuffs:		dc.l	0,0,0,0,0,0,0,0
PBuff0:		dc.l	0,0,0,0,0,0,0		;PT,Len,Per,PT2,Len2,Per2
PBuff1:		dc.l	0,0,0,0,0,0,0
PBuff2:		dc.l	0,0,0,0,0,0,0
PBuff3:		dc.l	0,0,0,0,0,0,0
PBuff4:		dc.l	0,0,0,0,0,0,0
PBuff5:		dc.l	0,0,0,0,0,0,0
PBuff6:		dc.l	0,0,0,0,0,0,0
PBuff7:		dc.l	0,0,0,0,0,0,0

***************************************
* File-System *************************
***************************************

* a0: Loadname ************************

FileSystem:	move.l	a0,-(sp)
		bsr.L	ClearCursor
		bsr.L	ClearPlane
		moveq	#0,d0
		bsr.L	SetPlanePT
		move.l	(sp)+,a0
		move.l	a7,FSInitStack
		moveq	#1,d0
		moveq	#5,d1
		bsr.L	PrintXY
		lea	FSIText(pc),a0
		bsr.L	PrintText
		lea	FSIRenders(pc),a0
		bsr.L	InvRenders
		bsr.L	AllocFS
		lea	FSExTable(pc),a0
		clr.l	(a0)+
		clr.w	(a0)
		moveq	#-1,d0
		move.l	d0,OldReqPos
		move.l	OldVBIInt+2(pc),FSOldJmp+2
		move.l	#FSInterrupt,$6c.w
		bsr.L	PrintDrawer
		bsr.L	PrintFile
NewDir:		bsr.L	ReadDir
FSExIn:		move.w	ExJmp(pc),d0
		beq.s	FSExIn
		clr.w	ExJmp
		cmp.w	#100,d0
		bge.s	FSEx2
		subq.w	#1,d0
		lea	ExJmpTable(pc),a0
		add.w	d0,d0
		add.w	d0,d0
		move.l	(a0,d0.w),a0
		jmp	(a0)

FSEx2:		cmp.w	#100,d0
		bne.s	FSE2_NoFile
		bsr.L	FileSelected
FSE2_NoFile:	cmp.w	#101,d0
		bne.s	FSE2_NoDir
		bsr.L	DirSelected
FSE2_NoDir:	bra.s	FSExIn

Cancel:		move.l	#NewVBIInt,$6c.w
		bsr.L	RD_UnLock
		bsr.s	FreeFS
		move.w	CursorY(pc),d0
		bsr.L	SetPlanePT
		bsr.L	PrintPattern
		moveq	#-1,d0
		rts

FSInitStack:	dc.l	0

FSOk:		move.l	#NewVBIInt,$6c.w
		bsr.L	RD_UnLock
		bsr.L	GetFileLen
		move.l	d0,-(sp)
		bsr.s	FreeFS
		move.w	CursorY(pc),d0
		bsr.L	SetPlanePT
		bsr.L	PrintPattern
		move.l	(sp)+,d0
		rts

* Info Buffer reservieren *************

AllocFS:	move.l	#260,d0
		moveq	#0,d1
		move.l	4.w,a6
		jsr	-198(a6)
		move.l	d0,FileInfoBlock
		rts
FreeFS:		move.l	FileInfoBlock(pc),a1
		move.l	#260,d0
		move.l	4.w,a6
		jsr	-210(a6)
		bra.s	FreeBuffers

FileInfoBLock:	dc.l	0

* Buffers freigeben *******************

FreeBuffers:	clr.b	RefreshDirs
		clr.b	RefreshFiles
		move.l	FirstDir(pc),a5
		clr.l	FirstDir
		move.w	Dirs(pc),d7
		clr.w	Dirs
		clr.w	TopDir
		bsr.s	ListFree
		move.l	FirstFile(pc),a5
		clr.l	FirstFile
		move.w	Files(pc),d7
		clr.w	Files
		clr.w	TopFile
		bra.s	ListFree
LF_Loop:	move.l	a5,a1
		move.l	(a5),a5
		moveq	#40,d0
		move.l	4.w,a6
		jsr	-210(a6)
ListFree:	dbf	d7,LF_Loop
		rts

* Directory lesen *********************

ReadDir:	bsr.s	FreeBuffers
		moveq	#-1,d0
		move.w	d0,ExJmp
		move.l	d0,OldReqPos
		bsr.L	ClearParts
		st	RefreshDirs
		st	RefreshFiles
		clr.w	ExJmp
		bsr.s	RD_UnLock
		move.l	#DrawerText,d1
		moveq	#-2,d2
		move.l	DosBase(pc),a6
		jsr	Lock(a6)
		move.l	d0,ActLock
		beq.s	RD_Ex
		move.l	ActLock(pc),d1
		move.l	FileInfoBlock(pc),d2
		move.l	DosBase(pc),a6
		jsr	Examine(a6)
		tst.l	d0
		beq.s	RD_UnLock
RD_Loop:	move.w	ExJmp(pc),d0
		beq.s	RD_Cont
		cmp.w	#100,d0
		bne.s	RD_Ex
		clr.w	ExJmp
		bsr.L	FileSelected
RD_Cont:	move.l	ActLock(pc),d1
		move.l	FileInfoBlock(pc),d2
		move.l	DosBase(pc),a6
		jsr	ExNext(a6)
		tst.l	d0
		beq.s	RD_UnLock
		move.l	FileInfoBlock(pc),a0
		tst.l	4(a0)
		bmi.s	RD_NoDir
		bsr.s	AddDir
		bra.s	RD_Loop
RD_NoDir:	bsr.s	AddFile
		bra.s	RD_Loop
RD_Ex:		rts
RD_UnLock:	move.l	ActLock(pc),d1
		beq.s	RDUL_Ex
		clr.l	ActLock
		move.l	DosBase(pc),a6
		jsr	UnLock(a6)
RDUL_Ex:	rts

ActLock:	dc.l	0

* File oder Dir in Liste einfuegen ****

AddFile:	clr.b	RefreshFiles
		lea	FirstFile(pc),a5
		bsr.s	AddFileIn
		addq.w	#1,Files
		st	RefreshFiles
		rts
AddDir:		clr.b	RefreshDirs
		lea	FirstDir(pc),a5
		bsr.s	AddFileIn
		addq.w	#1,Dirs
		st	RefreshDirs
		rts
AddFileIn:	bsr.L	AllocFile	;a4:PT
AFI_Next:	tst.l	(a5)
		beq.s	AFI_Last
		move.l	(a5),a1
		bsr.L	AFI_Compare
		bmi.s	AFI_Ins
		move.l	(a5),a5
		bra.s	AFI_Next
AFI_Ins:	move.l	(a5),a3
		move.l	a4,(a5)
		move.l	a3,(a4)+
		bra.s	AFI_SetData
AFI_Last:	move.l	a4,(a5)
		clr.l	(a4)+
AFI_SetData:	move.l	FileInfoBlock(pc),a0
		move.l	124(a0),(a4)+
		addq.w	#8,a0
		moveq	#30,d0
AF_CopyName:	move.b	(a0)+,(a4)+
		dbf	d0,AF_CopyName
		clr.b	(a4)
		rts

* File-Laenge ermitteln ***************

GetFileLen:	lea	DrawerText(pc),a0
		lea	FullFileText(pc),a1
		moveq	#0,d1
GFL_Loop1:	move.b	(a0)+,d0
		beq.s	GFL_Next
		move.b	d0,(a1,d1.w)
		addq.w	#1,d1
		bra.s	GFL_Loop1
GFL_Next:	tst.w	d1
		beq.s	GFL_NoDir
		cmp.b	#':',-1(a1,d1.w)
		beq.s	GFL_NoDir
		move.b	#'/',(a1,d1.w)
		addq.w	#1,d1
GFL_NoDir:	lea	FileText(pc),a0
GFL_Loop2:	move.b	(a0)+,d0
		beq.s	GFL_NameReady
		move.b	d0,(a1,d1.w)
		addq.w	#1,d1
		bra.s	GFL_Loop2
GFL_NameReady:	clr.b	(a1,d1.w)
		move.l	DosBase(pc),a6
		move.l	a1,d1
		moveq	#-2,d2
		jsr	Lock(a6)
		move.l	d0,d7
		beq.s	GFL_Error
		move.l	d7,d1
		move.l	FileInfoBlock(pc),d2
		jsr	Examine(a6)
		tst.l	d0
		beq.s	GFL_UnlockError
		move.l	d7,d1
		jsr	UnLock(a6)
		move.l	FileInfoBlock(pc),a0
		move.l	124(a0),d0
		rts
GFL_UnLockError:move.l	d7,d1
		jsr	UnLock(a6)
GFL_Error:	moveq	#0,d0
		rts

FullFileText:	blk.w	72,0

* Entry reservieren *******************

AllocFile:	moveq	#40,d0
		moveq	#0,d1
		move.l	4.w,a6
		jsr	-198(a6)
		move.l	d0,a4
		rts

AFI_Compare:	move.l	FileInfoBlock(pc),a0
		addq.w	#8,a0
		addq.w	#8,a1
		moveq	#96,d2
		moveq	#32,d3
AFI_CharLoop:	move.b	(a0)+,d0
		beq.s	AFI_Not
		move.b	(a1)+,d1
		beq.s	AFI_Ok
		cmp.b	d2,d0
		blt.s	AFI_FOk
		sub.b	d3,d0
AFI_FOk:	cmp.b	d2,d1
		blt.s	AFI_SOk
		sub.b	d3,d1
AFI_SOk:	cmp.b	d0,d1
		beq.s	AFI_CharLoop
		sgt	d0
		tst.b	d0
		rts
AFI_Ok:		moveq	#0,d0
		rts
AFI_Not:	moveq	#-1,d0
		rts

Dirs:		dc.w	0
Files:		dc.w	0
FirstDir:	dc.l	0
FirstFile:	dc.l	0
DrawerText:	blk.b	70,0
FileText:	blk.b	70,0

* Parts loeschen **********************

ClearParts:	move.l	Plane(pc),a0
		lea	80*6*9+2(a0),a0
		move.w	#29*6-1,d1
CP_LLoop:	moveq	#8,d0
CP_Loop1:	clr.l	(a0)+
		dbf	d0,CP_Loop1
		addq.w	#4,a0
		moveq	#8,d0
CP_Loop2:	clr.l	(a0)+
		dbf	d0,CP_Loop2
		addq.w	#4,a0
		dbf	d1,CP_LLoop
		rts

* File System-Interrupt ***************

FSInterrupt:	btst	#5,$dff01f
		beq.s	FSOldJmp
		movem.l	d0-d7/a0-a6,-(sp)
		bsr.L	KeyRepHandler
		bsr.L	ControlMouse
		tst.w	ExJmp
		bne.s	FSNotExecuted
		lea	FSExTable(pc),a0
		bsr.L	Executer
		bsr.s	CheckRequester
FSNotExecuted:	tst.b	RefreshDirs
		beq.s	FSNoDirs
		bsr.L	PrintDirs
FSNoDirs:	tst.b	RefreshFiles
		beq.s	FSNoFiles
		bsr.L	PrintFiles
FSNoFiles:	movem.l	(sp)+,d0-d7/a0-a6
FSOldJmp:	jmp	0

* Check ob Maus ueber File oder Dir ***

CheckRequester:	btst	#6,$bfe001
		bne.s	CR_NotSelected
		tst.b	MouseFlag
		bne.s	CR_Selected
		movem.w	OldReqPos(pc),d0-d1
		tst.w	d0
		bmi.s	CR_NotSelected
		sub.w	#12,d1
		cmp.w	#2,d0
		beq.s	CR_DirSelected
		add.w	TopFile(pc),d1
		move.w	d1,SelectedFile
		move.w	#100,ExJmp
		st	MouseFlag
		bra.s	CR_Selected
CR_DirSelected:	add.w	TopDir(pc),d1
		move.w	d1,SelectedDir
		move.w	#101,ExJmp
		st	MouseFlag
		bra.s	CR_Selected
CR_NotSelected:	sf	MouseFlag
CR_Selected:	movem.w	MousePos(pc),d0-d1
		cmp.w	#2*8,d0
		blt.s	CR_Noo
		cmp.w	#78*8,d0
		bge.s	CR_Noo
		cmp.w	#42*8,d0
		bge.s	CR_Files
		cmp.w	#38*8,d0
		blt.s	CR_Dirs
CR_Noo:		bra.L	ClearOldReq

CR_Files:	cmp.w	#42*12,d1
		bge.s	CRF_Add
		cmp.w	#13*12,d1
		blt.s	CRF_Sub
		moveq	#42,d0
		sub.w	#13*12,d1
		divu	#12,d1
		add.w	#13,d1
		move.l	d0,d2
		swap	d2
		move.w	d1,d2
		cmp.l	OldReqPos(pc),d2
		beq.s	CRF_Ex
		tst.w	OldReqPos
		bmi.s	CRF_Inv
		sf	MouseFlag
CRF_Inv:	bsr.L	ClearOldReq
		bsr.L	InvertReq
CRF_Ex:		rts
CRF_Add:	move.w	Files(pc),d0
		sub.w	#30,d0
		cmp.w	TopFile(pc),d0
		blt.L	ClearOldReq
		addq.w	#1,TopFile
		st	RefreshFiles
		bra.L	ClearOldReq
CRF_Sub:	tst.w	TopFile
		beq.s	ClearOldReq
		subq.w	#1,TopFile
		st	RefreshFiles
		bra.s	ClearOldReq

* Maus ueber Directory ****************

CR_Dirs:	cmp.w	#42*12,d1
		bge.s	CRD_Add
		cmp.w	#13*12,d1
		blt.s	CRD_Sub
		moveq	#2,d0
		sub.w	#13*12,d1
		divu	#12,d1
		add.w	#13,d1
		move.l	d0,d2
		swap	d2
		move.w	d1,d2
		cmp.l	OldReqPos(pc),d2
		beq.s	CRD_Ex
		tst.w	OldReqPos
		bmi.s	CRD_Inv
		sf	MouseFlag
CRD_Inv:	bsr.s	ClearOldReq
		bsr.s	InvertReq
CRD_Ex:		rts
CRD_Add:	move.w	Dirs(pc),d0
		sub.w	#30,d0
		cmp.w	TopDir(pc),d0
		blt.s	ClearOldReq
		addq.w	#1,TopDir
		st	RefreshDirs
		bra.s	ClearOldReq
CRD_Sub:	tst.w	TopDir
		beq.s	ClearOldReq
		subq.w	#1,TopDir
		st	RefreshDirs
		bra.s	ClearOldReq
MouseFlag:	dc.w	0
ClearOldReq:	movem.w	d0-d1,-(sp)
		movem.w	OldReqPos(pc),d0-d1
		tst.w	d0
		bmi.s	COR_Ex
		bsr.s	InvertReq
		moveq	#-1,d0
		move.l	d0,OldReqPos
COR_Ex:		movem.w	(sp)+,d0-d1
		rts
InvertReq:	movem.w	d0-d1,OldReqPos
		move.l	MenuPlane(pc),a0
		add.w	d0,a0
		mulu	#6*80,d1
		add.l	d1,a0
		moveq	#4,d1
IR_Loop1:	moveq	#8,d0
IR_Loop2:	not.l	(a0)+
		dbf	d0,IR_Loop2
		lea	44(a0),a0
		dbf	d1,IR_Loop1
		rts

OldReqPos:	dc.l	0

* Directories oder Files ausgeben *****

PrintDirs:	cmp.w	#42,OldReqPos
		beq.s	PD_NoClear
		bsr.s	ClearOldReq
PD_NoClear:	clr.b	RefreshDirs
		lea	FirstDir(pc),a5
		move.w	Dirs(pc),d7
		move.w	TopDir(pc),d6
		sub.w	d6,d7
		moveq	#2,d5
		bra.s	PrintEntries
PrintFiles:	cmp.w	#2,OldReqPos
		beq.s	PF_NoClear
		bsr.s	ClearOldReq
PF_NoClear:	clr.b	RefreshFiles
		lea	FirstFile(pc),a5
		move.w	Files(pc),d7
		move.w	TopFile(pc),d6
		sub.w	d6,d7
		moveq	#42,d5
		bra.s	PrintEntries
PE_Loop2:	move.l	(a5),a5
PrintEntries:	dbf	d6,PE_Loop2
		moveq	#13,d6
		cmp.w	#29,d7
		blt.s	PE_In
		moveq	#29,d7
		bra.s	PE_In
PE_Loop:	move.w	d5,d0
		move.w	d6,d1
		bsr.s	ClearLine
		move.l	(a5),a5
		lea	8(a5),a0
		move.w	d5,d0
		move.w	d6,d1
		bsr.L	PrintXY
		addq.w	#1,d6
PE_In:		dbf	d7,PE_Loop
		rts
RefreshDirs:	dc.b	0
RefreshFiles:	dc.b	0
TopFile:	dc.w	0
TopDir:		dc.w	0

* Entry-Line loeschen *****************
* <d0:XPos <d1:YPos *******************

ClearLine:	move.l	MenuPlane(pc),a0
		add.w	d0,a0
		mulu	#6*80,d1
		add.l	d1,a0
		moveq	#5,d1
CL_Loop2:	moveq	#8,d0
CL_Loop:	clr.l	(a0)+
		dbf	d0,CL_Loop
		lea	44(a0),a0
		dbf	d1,CL_Loop2
		rts

* Int-ausfuehrungstable ***************

FSExTable:	dc.l	0
		dc.w	0
		dc.l	FSGD,FSPD
		dc.w	1,7,78,7
		dc.l	FSGF,FSOKK
		dc.w	1,8,78,8
		dc.l	FSCA,0
		dc.w	1,9,6,9
		dc.l	FSRAM,0
		dc.w	9,9,12,9
		dc.l	FSDF0,0
		dc.w	14,9,17,9
		dc.l	FSDF1,0
		dc.w	19,9,22,9
		dc.l	FSDF2,0
		dc.w	24,9,27,9
		dc.l	FSDF3,0
		dc.w	29,9,32,9
		dc.l	FSDH0,0
		dc.w	34,9,37,9
		dc.l	FSDH1,0
		dc.w	39,9,42,9
		dc.l	0
FSGD:		moveq	#1,d0
		bra.s	FSEX
FSCA:		moveq	#2,d0
		bra.s	FSEX
FSRAM:		moveq	#3,d0
		bra.s	FSEX
FSDF0:		moveq	#4,d0
		bra.s	FSEX
FSDF1:		moveq	#5,d0
		bra.s	FSEX
FSDF2:		moveq	#6,d0
		bra.s	FSEX
FSDF3:		moveq	#7,d0
		bra.s	FSEX
FSGF:		moveq	#8,d0
		bra.s	FSEX
FSPD:		moveq	#9,d0
		bra.s	FSEX
FSOKK:		moveq	#10,d0
		bra.s	FSEX
FSDH0:		moveq	#11,d0
		bra.s	FSEX
FSDH1:		moveq	#12,d0
		bra.s	FSEX
FSEX:		move.w	d0,ExJmp
		rts

ExJmp:		dc.w	0
ExJmpTable:	dc.l	GetDrawer,Cancel,SetRam
		dc.l	Setdf0,Setdf1,Setdf2,Setdf3,GetFile
		dc.l	ParentDir,FSOK
		dc.l	SetDh0,SetDh1

* Funktion 100 >> File selektiert *****

FileSelected:	lea	FirstFile(pc),a5
		lea	FileText(pc),a0
		move.w	SelectedFile(pc),d0
		bra.s	FS_In
FS_Loop1:	move.l	(a5),d1
		beq.s	FS_Ex
		move.l	d1,a5
FS_In:		dbf	d0,FS_Loop1
		move.l	a0,a4
		addq.w	#8,a5
		move.l	a5,a1
		moveq	#19,d0
FS_Loop3:	cmpm.b	(a0)+,(a1)+
		bne.s	FS_New
		dbf	d0,FS_Loop3
		move.l	FSInitStack(pc),a7
		bra.L	FSOk
FS_New:		move.l	a4,a0
		move.l	a5,a1
		moveq	#19,d0
FS_Loop2:	move.b	(a5)+,(a0)+
		dbf	d0,FS_Loop2
		bsr.L	PrintFile
FS_Ex:		rts

SelectedFile:	dc.w	0

* Funktion 101 >> Directory selektiert*

DirSelected:	lea	FirstDir(pc),a5
		move.w	SelectedDir(pc),d0
		bra.s	DS_In
DS_Loop1:	move.l	(a5),d1
		beq.s	DS_Ex
		move.l	d1,a5
DS_In:		dbf	d0,DS_Loop1
		addq.w	#8,a5
		lea	DrawerText(pc),a1
		moveq	#-1,d0
DS_CheckEnd:	addq.w	#1,d0
		tst.b	(a1,d0.w)
		bne.s	DS_CheckEnd
		move.w	d0,d2
		beq.s	DS_Ini
		move.b	-1(a1,d0.w),d1
		cmp.b	#'/',d1
		beq.s	DS_Ini
		cmp.b	#':',d1
		beq.s	DS_Ini
		move.b	#'/',(a1,d0.w)
		addq.w	#1,d0
DS_Ini:		cmp.w	#70,d0
		bge.s	DS_Old
		move.b	(a5)+,d1
		beq.s	DS_CopyReady
		move.b	d1,(a1,d0.w)
		addq.w	#1,d0
		bra.s	DS_Ini
DS_CopyReady:	cmp.w	#70,d0
		bge.s	DS_Old
		clr.b	(a1,d0.w)
		bsr.L	PrintDrawer
		move.l	FSInitStack(pc),a7
		bra.L	NewDir
DS_Old:		clr.b	(a1,d2.w)
DS_Ex:		bra.L	PrintDrawer

SelectedDir:	dc.w	0

GetDrawer:	lea	DrawerText(pc),a0
		moveq	#8,d0
		moveq	#7,d1
		moveq	#69,d2
		bsr.L	GetText
		bra.L	NewDir

GetFile:	lea	FileText(pc),a0
		moveq	#8,d0
		moveq	#8,d1
		moveq	#69,d2
		bsr.L	GetText
		bra.L	FSOk
SetRam:		move.l	#'ram:',d0
		bra.s	NewDrawer
SetDf0:		move.l	#'df0:',d0
		bra.s	NewDrawer
SetDf1:		move.l	#'df1:',d0
		bra.s	NewDrawer
SetDf2:		move.l	#'df2:',d0
		bra.s	NewDrawer
SetDf3:		move.l	#'df3:',d0
		bra.s	NewDrawer
SetDh0:		move.l	#'dh0:',d0
		bra.s	NewDrawer
SetDh1:		move.l	#'dh1:',d0
		bra.s	NewDrawer
NewDrawer:	lea	DrawerText(pc),a0
		move.l	d0,(a0)+
		clr.b	(a0)
		bsr.s	PrintDrawer
		bra.L	NewDir

* Parent Dir **************************

ParentDir:	lea	DrawerText(pc),a0
		moveq	#-1,d0
PD_SearchEnd:	addq.w	#1,d0
		tst.b	(a0,d0.w)
		bne.s	PD_SearchEnd
		tst.w	d0
		beq.s	PD_NoParent
		subq.w	#1,d0
		move.b	(a0,d0.w),d1
		cmp.b	#':',d1
		beq.s	PD_Sub
		cmp.b	#'/',d1
		bne.s	PD_NoSub
PD_Sub:		subq.w	#1,d0
		bmi.s	PD_DirFound
PD_NoSub:	subq.w	#1,d0
		bmi.s	PD_DirFound
		move.b	(a0,d0.w),d1
		cmp.b	#':',d1
		beq.s	PD_DirFound
		cmp.b	#'/',d1
		bne.s	PD_NoSub
		subq.w	#1,d0
PD_DirFound:	clr.b	1(a0,d0.w)
		bsr.s	PrintDrawer
PD_NoParent:	bra.L	NewDir

* Drawer ausgeben *********************

PrintDrawer:	moveq	#8,d0
		moveq	#7,d1
		bsr.L	GI_ClearPart
		lea	DrawerText(pc),a0
		moveq	#8,d0
		moveq	#7,d1
		bra.L	PrintXY

* File ausgeben ***********************

PrintFile:	moveq	#8,d0
		moveq	#8,d1
		bsr.L	GI_ClearPart
		lea	FileText(pc),a0
		moveq	#8,d0
		moveq	#8,d1
		bra.L	PrintXY

* Text an a0 d0 Bytes holen ***********

GetText:	movem.w	d0-d1,GT_PPos
		move.l	a0,a5
		move.w	d2,d7
		bsr.L	GI_ClearPart
		move.l	a5,a0
		moveq	#69,d0
GT_Clear:	clr.b	(a0)+
		dbf	d0,GT_Clear
		clr.b	ActKey
		moveq	#0,d6
		clr.w	GT_EndFlag
		bsr.L	SetTextCursor
GT_Loop:	bsr.s	GT_GetIt
		move.l	a5,a0
		movem.w	GT_PPos(pc),d0-d1
		bsr.L	PrintXY
		bsr.L	SetTextCursor
		tst.w	GT_EndFlag
		beq.s	GT_Loop
		cmp.w	d6,d7
		bne.s	GT_Not
		bsr.L	ClrTextCursor
GT_Not:		rts
GT_GetIt:	tst.w	ExJmp
		bne.L	GT_Exec
		move.b	ActKey(pc),d0
		beq.s	GT_GetIt
		clr.b	ActKey
		move.l	a5,a0
		cmp.b	#32,d0
		blt.s	GT_Extra
		move.b	d0,(a0,d6.w)
		cmp.w	d7,d6
		beq.s	GT_LastChar
		addq.w	#1,d6
GT_LastChar:	rts
GT_Extra:	cmp.b	#4,d0
		beq.s	GT_End
		cmp.b	#1,d0
		beq.s	GT_Delete
		bra.s	SetTextCursor
GT_End:		st	GT_EndFlag
		rts
GT_Delete:	tst.w	d6
		beq.s	GT_DEnd
		tst.b	(a0,d7.w)
		bne.s	GT_DLast
		subq.w	#1,d6
		clr.b	(a0,d6.w)
GT_DEnd:	movem.w	GT_PPos(pc),d0-d1
		add.w	d6,d0
		lea	GT_DelText(pc),a0
		bra.L	PrintXY
GT_DelText:	dc.b	'  ',0,0
GT_DLast:	clr.b	(a0,d6.w)
		movem.w	GT_PPos(pc),d0-d1
		add.w	d6,d0
		lea	GT_DelText+1(pc),a0
		bra.L	PrintXY
SetTextCursor:	movem.w	GT_PPos(pc),d0-d1
		add.w	d6,d0
		movem.w	d0-d1,STC_Old
		bra.L	InvertCursor
ClrTextCursor:	movem.w	STC_Old(pc),d0-d1
		bra.L	InvertCursor
GI_ClearPart:	move.l	MenuPlane(pc),a0
		add.w	d0,a0
		mulu	#6*80,d1
		add.l	d1,a0
		moveq	#4,d1
CP_2:		moveq	#69,d0
CP_1:		clr.b	(a0)+
		dbf	d0,CP_1
		lea	10(a0),a0
		dbf	d1,CP_2
		rts
GT_Exec:	move.l	FSInitStack(pc),a7
		bsr.s	ClrTextCursor
		bra	FSExIn

STC_Old:	dc.l	0
GT_PPos:	dc.l	0
GT_EndFlag:	dc.w	0

FSIRenders:	dc.w	1,12,38,42
		dc.w	41,12,78,42
		dc.w	-1
FSIText:	dc.b	1,7,'drawer:',-1
		dc.b	1,8,'file..:',-1
		dc.b	1,9,'cancel  ram: df0: df1: df2: df3: dh0: dh1:'
		dc.b	' --------1-------- --------2--------',-1
		dc.b	1,11,'directories:',-1
		dc.b	41,11,'files:',0,0

***************************************
* SAMPLER *****************************
***************************************

EditSample:	bsr.L	ClearCursor
		bsr.L	ClearPlane
		bsr.L	AllocES
		moveq	#0,d0
		bsr.L	SetPlanePT
		lea	ES_ExTable(pc),a0
		clr.l	(a0)+
		clr.w	(a0)
		clr.w	ES_QuitFlag
		move.w	#64,ES_Volume
		lea	ES_InitText(pc),a0
		bsr.L	PrintText
		bsr.L	PrintEditedSample
ES_Raster:	bsr.L	WaitTOP
		lea	ES_ExTable(pc),a0
		bsr.L	Executer
		bsr.s	ES_KeyHandler
		tst.w	ES_NewDraw
		beq.s	ES_NoNew
		btst	#6,$bfe001
		beq.s	ES_NoNew
		btst	#2,$dff016
		beq.s	ES_NoNew
		tst.w	ES_NewVol
		beq.s	ES_NoNewVol
		bsr.L	CompNewSample
ES_NoNewVol:	bsr.L	PlotSample
ES_NoNew:	tst.w	ES_QuitFlag
		beq.s	ES_Raster
		tst.w	ES_NewDraw
		beq.s	ES_NoNew2
ES_NoNew2:	bsr.L	CopyUp
		bsr.L	FreeES
		move.w	CursorY(pc),d0
		bsr.L	SetPlanePT
		bra.L	PrintPattern
ES_NewDraw:	dc.w	0
ES_NewVol:	dc.w	0

* Note spielen ************************

ES_KeyHandler:	move.b	ActKey(pc),d0
		beq.s	ESKH_Ex
		clr.b	ActKey
		bsr.L	TestNoteKey
		bmi.s	ESKH_Ex
		move.l	ActPeriodTab(pc),a1
		move.b	(a1,d0.w),d1
		bmi.s	ESKH_Ex
		lea	ES_ActChannel(pc),a0
		move.w	(a0),d0
		addq.w	#1,(a0)
		and.w	#$3,(a0)
		bsr.L	PlayNote
ESKH_Ex:	rts
ES_ActChannel:	dc.w	0

* Sample-Speicher reservieren *********

AllocES:	move.l	4.w,a6
		move.l	#$40*4,d0
		moveq	#0,d1
		jsr	-198(a6)
		move.l	d0,PS_YTab
		move.l	d0,a0
		move.l	MenuPlane(pc),a1
		lea	80*6*10(a1),a1
		moveq	#$3f,d0
AES_Loop:	move.l	a1,(a0)+
		lea	80(a1),a1
		dbf	d0,AES_Loop
		move.l	#$80,d0
		moveq	#0,d1
		jsr	-198(a6)
		move.l	d0,VolTable
		rts
FreeES:		move.l	4.w,a6
		move.l	PS_YTab(pc),a1
		move.l	#$40*4,d0
		jsr	-210(a6)
		move.l	VolTable(pc),a1
		move.l	#$80,d0
		jmp	-210(a6)

PS_YTab:	dc.l	0
VolTable:	dc.l	0

* Sample hochkopieren *********************

CopyUp:		lea	SampleTab(pc),a0
		move.w	ActSample(pc),d0
		lsl.w	#3,d0
		move.l	(a0,d0.w),d1
		beq.s	CU_Not
		move.l	d1,a1
		move.l	4(a0,d0.w),d0
		beq.s	CU_Not
		cmp.l	ActCSLen(pc),d0
		bne.s	CU_Not
		move.l	ActCSPT(pc),d0
		beq.s	CU_Not
		move.l	d0,a0
		move.l	ActCSLen(pc),d0
		beq.s	CU_Not
CU_Loop:	move.b	(a0)+,(a1)+
		subq.l	#1,d0
		bne.s	CU_Loop
CU_Not:		rts

* Sample ausgeben *************************

PrintEditedSample:lea	PES_SampleName(pc),a0
		bsr.L	PrintText
		lea	SH_Samples(pc),a0
		move.w	ActSample(pc),d0
		lsl.w	#5,d0
		add.w	d0,a0
		tst.b	(a0)
		bne.s	PES_NotUnnamed
		lea	PES_UnnamedTxt(pc),a0
		bsr.L	PrintText
		bra.s	PES_Ready
PES_NotUnnamed:	moveq	#16,d0
		moveq	#7,d1
		bsr.L	PrintXY
PES_Ready:	bra.s	PlotSample

* Sample plotten **********************

PlotSample:	sf	ES_NewDraw
		bsr.L	ClearPlotPart
		move.l	ActCSPT(pc),d0
		beq.s	PS_Ex
		move.l	d0,a0
		move.l	ActCSLen(pc),d1
		beq.s	PS_Ex
		move.l	PS_YTab(pc),a2
		moveq	#$7e,d3
		move.l	#640*$1000,d2
		lsr.l	#4,d1
		beq.s	PS_OrigPlot
		divu	d1,d2
		and.l	#$ffff,d2
		beq.s	PS_OrigPlot
		moveq	#0,d7
PS_Loop:	move.b	(a0)+,d0
		and.w	d3,d0
		add.w	d0,d0
		move.l	(a2,d0.w),a1
		move.w	d7,d1
		lsr.w	#3,d1
		moveq	#7,d0
		sub.w	d7,d0
		bset	d0,(a1,d1.w)
		swap	d7
		add.l	d2,d7
		swap	d7
		cmp.w	#640,d7
		blt.s	PS_Loop
PS_Ex:		rts
PS_OrigPlot:	move.l	ActCSPT(pc),a0
		move.l	ActCSLen(pc),d6
		subq.w	#1,d6
		move.l	PS_YTab(pc),a2
		moveq	#$7e,d3
		moveq	#0,d7
PSOP_Loop:	move.b	(a0)+,d0
		and.w	d3,d0
		add.w	d0,d0
		move.l	(a2,d0.w),a1
		move.w	d7,d1
		lsr.w	#3,d1
		moveq	#7,d0
		sub.w	d7,d0
		bset	d0,(a1,d1.w)
		addq.w	#1,d7
		dbf	d6,PSOP_Loop
		rts

* Plot-Part loeschen ******************

ClearPlotPart:	move.l	MenuPlane(pc),a0
		lea	80*10*6(a0),a0
		moveq	#0,d1
		move.w	#20*64-1,d0
CPP_Loop:	move.l	d1,(a0)+
		dbf	d0,CPP_Loop
		rts

* Sample neu kopieren+berechnen *******

CompNewSample:	move.l	VolTable(pc),a0
		move.w	ES_Volume(pc),d0
		moveq	#64,d3
		sub.w	d0,d3
		moveq	#0,d1
CNS_Loop:	moveq	#0,d2
		tst.w	d0
		beq.s	CNS_Clr
		move.w	d1,d2
		mulu	d0,d2
		lsr.w	#6,d2
CNS_Clr:	add.w	d3,d2

		cmp.w	#$7f,d2
		blt.s	CNS_Ok1
		move.w	#$7f,d2
CNS_Ok1:	tst.w	d2
		bgt.s	CNS_Ok2
		moveq	#0,d2
CNS_Ok2:	move.b	d2,(a0)+
		addq.w	#1,d1
		cmp.w	#$80,d1
		bne.s	CNS_Loop
		lea	SampleTab(pc),a0
		move.w	ActSample(pc),d0
		lsl.w	#3,d0
		move.l	(a0,d0.w),d0
		beq.s	CNS_Noo
		move.l	d0,a0
		move.l	ActCSPT(pc),d0
		beq.s	CNS_Noo
		move.l	d0,a1
		move.l	VolTable(pc),a2
		move.l	ActCSLen(pc),d0
		subq.l	#2,d0
		ble.s	CNS_Noo
		move.w	#$4040,(a1)+
		moveq	#0,d1
		moveq	#$7f,d2
CNS_Loop2:	move.b	(a0)+,d1
		and.b	d2,d1
		move.b	(a2,d1.w),d1
		move.b	d1,(a1)+
		subq.l	#1,d0
		bne.s	CNS_Loop2
CNS_Noo:	clr.w	ES_NewVol
		rts

PES_SampleName:	dc.b	1,7,'Actual Sample:',0
PES_UnnamedTxt:	dc.b	16,7,'Unnamed',0
ES_InitText:	dc.b	1,5,'Sample Editor V1.0',-1
		dc.b	1,23,'Exit Volume:064 DELTA-Filter',0,0

ES_ExTable:	dc.l	0
		dc.w	0
		dc.l	ES_Quit,0
		dc.w	1,23,4,23
		dc.l	VolumeUp,VolumeDown
		dc.w	6,23,15,23
		dc.l	DeltaFilter,0
		dc.w	17,23,28,23
		dc.l	0
ES_Quit:	st	ES_QuitFlag
		rts
ES_QuitFlag:	dc.w	0
VolumeUp:	cmp.w	#128,ES_Volume
		beq.s	VU_Ex
		addq.w	#1,ES_Volume
		st	ES_NewVol
		st	ES_NewDraw
		bsr.s	PrintES
VU_Ex:		rts
VolumeDown:	tst.w	ES_Volume
		beq.s	VD_Ex
		subq.w	#1,ES_Volume
		st	ES_NewVol
		st	ES_NewDraw
		bsr.s	PrintES
VD_Ex:		rts
ES_Volume:	dc.w	0
DeltaFilter:	move.l	ActCSPT(pc),d0
		beq.s	DF_Ex
		move.l	d0,a0
		move.l	ActCSLen(pc),d0
		subq.l	#4,d0
		ble.s	DF_Ex
		move.w	#$4040,(a0)
		addq.w	#1,a0
		moveq	#0,d1
		moveq	#0,d2
		moveq	#0,d3
		move.b	(a0)+,d1
DF_Loop:	move.b	(a0),d2
		move.b	1(a0),d3
		add.w	d1,d3
		lsr.w	#1,d3
		add.w	d2,d3
		lsr.w	#1,d3
		and.b	#$7f,d3
		move.b	(a0),d1
		move.b	d3,(a0)+
		subq.l	#1,d0
		bne.s	DF_Loop
DF_Filtered:	st	ES_NewDraw
		bsr.L	CopyUp
DF_Ex:		rts

* Alles im ES-Window ausgeben *********

PrintES:	moveq	#13,d0
		moveq	#23,d1
		move.w	ES_Volume(pc),d2
		bra.L	PrintDez3

***************************************
* DATEN *******************************
***************************************

CopperList:	dc.l	$1200000,$1220000,$1240000,$1260000
		dc.l	$1280000,$12a0000,$12c0000,$12e0000
		dc.l	$1300000,$1320000,$1340000,$1360000
		dc.l	$1380000,$13a0000,$13c0000,$13e0000
		dc.l	$8e0581,$9040c1,$92003c,$9400d0
		dc.l	$1800000,$182048f
		dc.l	$1a20c06,$1a40904,$1a60603
		dc.l	$1020000,$104003f
		dc.l	$1080000
		dc.l	$2b07fffe
CopMenuPlane:	dc.l	$e00000,$e20000
		dc.l	$1009200
		dc.l	$4307fffe
		dc.l	$1800022,$18200aa
CopPlane:	dc.l	$e00000,$e20000
		dc.w	$100
BplCon:		dc.w	$9200
		dc.l	$ffdffffe
		dc.l	$2d07fffe
		dc.l	$1000000
		dc.l	-2

FullPeriodTab:	dc.w	0,$358,$328,$2FA,$2D0,$2A6,$280,$25C,$23A,$21A
		dc.w	$1FC,$1E0,$1C5,$1AC,$194,$17D,$168,$153,$140
		dc.w	$12E,$11D,$10D,$FE,$F0,$E2,$D6,$CA,$BE
		dc.w	$B4,$AA,$A0,$97,$8F,$87,$7F,$78,$71
FullNoteTab:	dc.b	'--- c-1 c#1 d-1 d#1 e-1 f-1 f#1 g-1 g#1 a-1 a#1 b-1 '
		dc.b	'c-2 c#2 d-2 d#2 e-2 f-2 f#2 g-2 g#2 a-2 a#2 b-2 '
		dc.b	'c-3 c#3 d-3 d#3 e-3 f-3 f#3 g-3 g#3 a-3 a#3 b-3 '
NoteKeyTab:	dc.b	'zsxdcvgbhnjm'
		dc.b	',l.;/'
		dc.b	'q2w3er5t6y7u'
		dc.b	'i9o0p[=]\'
		dc.b	6,0
PeriodTab1:	dc.b	1,2,3,4,5,6,7,8,9,10,11,12
		dc.b	13,14,15,16,17
		dc.b	13,14,15,16,17,18,19,20,21,22,23,24
		dc.b	25,26,27,28,29,30,31,32,33
		dc.b	0
even
NoteTab1:	dc.b	'c-1 c#1 d-1 d#1 e-1 f-1 f#1 g-1 g#1 a-1 a#1 b-1 '
		dc.b	'c-2 c#2 d-2 d#2 e-2 '
		dc.b	'c-2 c#2 d-2 d#2 e-2 f-2 f#2 g-2 g#2 a-2 a#2 b-2 '
		dc.b	'c-3 c#3 d-3 d#3 e-3 f-3 f#3 g-3 g#3 '
		dc.b	'--- '
PeriodTab2:	dc.b	13,14,15,16,17,18,19,20,21,22,23,24
		dc.b	25,26,27,28,29
		dc.b	25,26,27,28,29,30,31,32,33,34,35,36
		dc.b	-1,-1,-1,-1,-1,-1,-1,-1,-1
		dc.b	0
even
NoteTab2:	dc.b	'c-2 c#2 d-2 d#2 e-2 f-2 f#2 g-2 g#2 a-2 a#2 b-2 '
		dc.b	'c-3 c#3 d-3 d#3 e-3 '
		dc.b	'c-3 c#3 d-3 d#3 e-3 f-3 f#3 g-3 g#3 a-3 a#3 b-3 '
		dc.b	'                                    '
		dc.b	'--- '
CursorTab:	dc.b	9 ,13,14,15,16
		dc.b	18,22,23,24,25
		dc.b	27,31,32,33,34
		dc.b	36,40,41,42,43
		dc.b	45,49,50,51,52
		dc.b	54,58,59,60,61
		dc.b	63,67,68,69,70
		dc.b	72,76,77,78,79
Z0Tab:		dc.b	'0123456789abcdefghijklmnopqrstuvwxyz'

SongHeader:
SH_Samples:	blk.b	[32*36],0	;Name(20), Len(4), RepSt(4), RepLen(4)
SH_Speed:	dc.b	6
SH_Len:		dc.b	1
SH_Patterns:	blk.b	128,0
SongHeaderEnd:

org $7f000-320
load $7f000-320

o:
Chars:		org	*+320
oe:
