_Begin:
*******************************************************************************
* Trainer Menu 4 Hellfire (in OS Framework)  Copyright İ 1996 Beldin/Hellfire *
* ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ *
* $Release	: 1.0 $                                                       *
* $Revision	: 1.0 $                                                       *
* $Date		: 10-03-96 $                                                  *
*                                                                             *
* $Author(s)	: Written by Beldin (In MC680x0 Assembly under Asm-One)       *
*                                                                             *
* $Purpose	: Generic trainer menu (100% PC Relative)                     *
*******************************************************************************

Yes		=	1
No		=	0

*-------------- The following decide if the relavent routines & vars are asm'd.
*-------------- Or included in the source.

SysFrame	=	Yes		; started from?  (No = NonDos)
ForReal		=	No		; train or test?
Keys		=	Yes		; shall we in-game keys?
BbsNums		=	Yes		; bbs nums advert?
Logo		=	Yes		; logo displayed?
Scroller	=	Yes
Info		=	Yes
Devpac		=	No

		SECTION	FRAME,CODE_C
		IFNE	Devpac
		opt	c-,p+
		ENDC

*-------------- Definition Includes.

		incdir	include:
		include	AGA_REGS.i

*-------------- Equates for screen sizes etc.

LogoWidth	=	320/8
LogoHeight	=	52
LogoDepth	=	4
LogoSize	=	LogoWidth*LogoHeight*LogoDepth

MenuWidth	=	640/8
MenuHeight	=	138+8
MenuDepth	=	1
MenuSize	=	MenuWidth*MenuHeight*MenuDepth

ScrollerWidth	=	816/8
ScrollerHeight	=	12
ScrollerDepth	=	1
ScrollerSize	=	ScrollerWidth*ScrollerHeight*ScrollerDepth

InfoWidth	=	640/8
InfoHeight	=	16
InfoDepth	=	1
InfoSize	=	InfoWidth*InfoHeight*InfoDepth

*******************************************************************************
		jmp	_ProgStart(pc)
*****************************************************************************
*-------------- Now is the time to loadseg the game file so we can patch it!

_GetFile:	jsr	_DosLoadSeg(pc)

*-------------- and build the hunk table from this.

		jsr	_FindHunks(pc)

		rts
*****************************************************************************
*-------------- Ok we want to train, but what?

_DoTrainer:	move.l	Mode(a4),d7
		beq.s	_Execute

.0:		btst.l	#0,d7
		beq.b	.1

.PatchTime:	move.w	#0,d0			; hunk number (0-9)
		jsr	_GetHunkPtr(pc)

		move.w	#$4a49,$3b7a(a0)
		move.w	#$4e71,$3b7c(a0)

.1:		btst.l	#1,d7
		beq.w	.2
.2:		btst.l	#2,d7
		beq.w	.3
.3:		btst.l	#3,d7
		beq.w	.4
.4:		btst.l	#4,d7
		beq.w	.5
.5:		btst.l	#5,d7
		beq.w	.6
.6:		btst.l	#6,d7
		beq.w	.7
.7:		btst.l	#7,d7
		beq.s	_Execute
		nop

*-------------- Execute file, by jumping to the address of the first hunk.

_Execute:	move.l	FileStart(a4),a0
		add.l	a0,a0
		add.l	a0,a0
		lea	4(a0),a1
		jmp	(a1)
*****************************************************************************
* GetHunkPtr()
* ----------------------------------------------------------------------------
*
* Get the hunk pointer.
*
* $Inputs:	d0.w:	Hunk number to get. (0-9)
* $Outputs:	a0:	Hunk pointer.
******************************************************************************
_GetHunkPtr:	asl.l	#2,d0			; make LONG
		lea	HunkTable(a4),a1
		move.l	(a1,d0),a0
		rts
*****************************************************************************
*-------------- We will use dos LOADSEG since we whant the hunk structure.

_DosLoadSeg:	move.l	$4.w,a6
		lea	.DosName(pc),a1
		moveq	#0,d0
		jsr	-552(a6)		; open library
		move.l	d0,d7
		move.l	d0,a6

		lea	Segment(pc),a0
		move.l	a0,d1
		jsr	-150(a6)		; LoadSeg
		move.l	d0,FileStart(a4)

		move.l	$4.w,a6
		move.l	d7,a1
		jsr	-414(a6)		; close library
		rts

.DosName:	dc.b	"dos.library",0
		even
Segment:	dc.b	"xxxxxxx",0
		even
*****************************************************************************
_FindHunks:	move.l	FileStart(a4),a1
		lea	HunkTable(a4),a6
.DoAgain:	move.l	a1,a0
		add.l	a0,a0
		add.l	a0,a0
		move.l	a0,d0
		tst.l	d0
		beq.s	.HunksDone
		move.l	(a0),a1
		addq.l	#4,D0
		move.l	d0,(a6)+
		bra.s	.DoAgain
.HunksDone:	rts
*******************************************************************************
*-------------- If it is to be a trainer for mfm disk then skip the _ProStart:

_ProgStart:	lea	Variables(pc),a4
		IFEQ	SysFrame
		jmp	_ItIsShell(pc)
		ENDC

		move.l	$4.w,a0
		move.l	$114(a0),a2
		tst.l	$ac(a2)
		bne.s	_ItIsShell
		lea	$5c(a2),a0
		move.l	$4.w,a6
		jsr	-$180(a6)
		lea	$5c(a2),a0
		jsr	-$174(a6)
		move.l	d0,WBStartUp(a4)

_ItIsShell:	jsr	_KillSys(pc)
		jsr	_GetMem(pc)

*-------------- Dissabled ints and save the old level 3.

		move.w	#$7fff,$dff09a
		move.l	VBRBase(a4),a1
		move.l	$6c(a1),OldLevel3(a4)

*-------------- Install a level 3 handler.

		lea	_MyLevel3(pc),a0
		move.l	VBRBase(a4),a1
		move.l	a0,$6c(a1)

*-------------- Turn on interupt status.

		move.w	#%1100000000100000,$dff09a	;intena

*-------------- And now do my code!

		jsr	_StartCode(pc)

*-------------- Do we want bbs number displayed?

		IFNE	BbsNums
		jsr	_DoBbsText(pc)
		ENDC

*-------------- Do we want in-game keys displayed?

		move.l	Mode(a4),d0
		btst.l	#7,d0
		beq.s	.NoKeys
		jsr	_DoKeysText(pc)

*-------------- Restore the old level 3.

.NoKeys:	move.l	VBRBase(a4),a1
		move.l	OldLevel3(a4),$6c(a1)

		jsr	_FreeMem(pc)
		jsr	_RestoreSys(pc)

		IFNE	SysFrame
		move.l	$4.w,a6
		tst.l	WBStartUp(a4)
		beq.s	_ItWasShell
		jsr	-$17a(a6)
		ENDC
_ItWasShell:	IFNE	ForReal
		jsr	_GetFile(pc)
		jmp	_DoTrainer(pc)
		ENDC

*-------------- Exit back to SHELL.

		moveq	#0,d0			; no return code
		rts				; exit.

_OpenError:	moveq	#-1,d0			; cannot open library.
		rts

_Error:		move.w	$dff006,$dff180
		jmp	_Error(pc)
*****************************************************************************
_KillSys:	move.l	$4.w,a6
		lea	GfxName(pc),a1
		clr.l	d0
		jsr	-552(a6)
		move.l	d0,a1
		move.l	d0,GfxBase(a4)

		move.l	38(a1),SystemCop(a4)
		move.l	34(a1),OldView(a4)
		move.l	a1,a6

		sub.l	a1,a1
		jsr	-$de(a6)
		jsr	-$10e(a6)
		jsr	-$10e(a6)
		jsr	-$1c8(a6)
		jsr	-$e4(a6)
	
		move.l	$4.w,a6
		clr.l	d0
		move.w	$128(a6),d0
		and.w	#$F,d0
		beq.s	_Done
		lea	_VBRCode(pc),a5
		jsr	-30(a6)			; supervisor
		move.l	d0,a0
		lea	_Done(pc),a1
		jmp	(a1)
_VBRCode:	dc.w	$4e7a,$0801
		rte

_Done:		move.l	d0,VBRBase(a4)
		move.w	$dff01c,OldInt(a4)
		move.w	$dff01e,OldIntR(a4)
		move.w	$dff002,OldDma(a4)
		jsr	BLITWAIT(pc)
		move.w	#$8000,d0
		or.w	d0,OldInt(a4)
		or.w	d0,OldIntR(a4)
		or.w	d0,OldDma(a4)
		move.w	#$7fff,d0
		move.w	d0,$dff096
		move.w	d0,$dff09a
		move.w	d0,$dff09c
		move.b	#$7f,$bfed01
		move.w	#%1000011111100000,$dff096
		rts
*****************************************************************************
_RestoreSys:	jsr	BLITWAIT(pc)
		move.w	#$7fff,$dff096
		move.w	#$7fff,$dff09a
		move.w	#$7fff,$dff09c
		move.w	OldDma(a4),$dff096
		move.w	OldInt(a4),$dff09a
		move.w	OldIntR(a4),$dff09c
		move.b	#$9b,$bfed01
		move.l	OldView(a4),a1
		move.l	GfxBase(a4),a6
		jsr     -$de(a6) 
		jsr     -$1ce(a6)
		move.l  $26(a6),$dff080
		move.l	$4.w,a6
		move.l	GfxBase(a4),a1
		jsr	-414(a6)
		rts
*******************************************************************************
		RSReset

NullSprite:	rs.l	3
OldInt:		rs.w	1
OldIntR:	rs.w	1
OldDma:		rs.w	1
SystemCop:	rs.l	1
VBRBase:	rs.l	1
OldLevel3:	rs.l	1
OldView:	rs.l	1
GfxBase:	rs.l	1
WBStartUp:	rs.l	1

LogoPtr:	rs.l	1
MenuPtr:	rs.l	1
ScrollerPtr:	rs.l	1
InfoPtr:	rs.l	1

Mouse_X:	rs.w	1
Mouse_Y:	rs.w	1
Mouse_DX:	rs.w	1
Mouse_DY:	rs.w	1
MouseControl:	rs.w	1
Option:		rs.w	1

Mode:		rs.l	1
QuitFlag:	rs.w	1
WordBuffer:	rs.b	10

FadeInfo:	rs.w	1
FadeDelay:	rs.w	1
InfoTextPtr:	rs.l	1

ScrollerPos:	rs.w	1
ScrollerDelay:	rs.w	1
ScrollerPause:	rs.w	1

FileStart:	rs.l	1
HunkTable:	rs.l	20

CounterDelay:	rs.w	1
CounterPtr:	rs.w	10		; label 4 counters (999)

VarsSize:	rs.b	0
Variables:	ds.b	VarsSize

GfxName:	dc.b	"graphics.library",0
		cnop	0,4
*****************************************************************************
*-------------- Initialise routines.

_StartCode:	lea	CustomBase,a5

*-------------- Make LogoPtr(a4) point at the incbin'd logo

		IFNE	Logo
		lea	LogoBin(pc),a0
		move.l	a0,LogoPtr(a4)
		ENDC

*-------------- Initialize the copper list screens etc.

		jsr	_InitPlanes(pc)
		jsr	_InitSprites(pc)
		jsr	_InitCopper(pc)

*-------------- Make copy of original mouse pos, 4 l8trs.

		move.w	joy0dat(a5),MouseControl(a4)

*-------------- Initialize some vars.

		lea	CounterPtr(a4),a0
		moveq	#10-1,d7
.Clr:		clr.w	(a0)+
		dbra	d7,.Clr

		lea	InfoText(pc),a0
		move.l	a0,InfoTextPtr(a4)

		clr.w	Option(a4)
		clr.l	Mode(a4)
		clr.w	QuitFlag(a4)
		move.w	#4,ScrollerDelay(a4)

		move.w	#-1,FadeInfo(a4)		; -1 = in 0 = out
		move.w	#5,FadeDelay(a4)
		move.w	#10,CounterDelay(a4)

		bsr	_InitTogs

*-------------- Display the heading title and aurthor, menu, and on/off's.

		bsr	VBLWAIT
		lea	HeadingText(pc),a0
		bsr	_PrintLines

		bsr	VBLWAIT
		lea	MenuText(pc),a0
		bsr	_PrintLines

		bsr	VBLWAIT
		lea	TogglesText(pc),a6
		bsr	_PrintToggles

		bsr	VBLWAIT
		bsr	_PrintInfo

*-------------- Main loop is all we need to do is check the mouse.

_MainLoop:	bsr	VBLWAIT
		bsr	_ReadMouse

		btst	#$0a,$dff016
		beq.s	.ModeOff

		btst	#6,$bfe001
		beq.s	.ModeOn

		bra.s	_MainLoop

*-------------- ModeOn/Off is to toggle the mode flags in Mode(a4) and
*-------------- display either on or off on the menu.

.ModeOff:	lea	Off.Msg(pc),a1
		lea	TogglesText(pc),a0

		clr.l	d1
		clr.l	d2
		move.w	Option(a4),d1
		cmp.w	#7,d1
		bgt.s	_MainLoop

		move.w	d1,d2
		mulu.w	#7,d2
		add.w	d2,a0

		tst.b	2(a0)
		bne.s	.IncVal

		move.l	Mode(a4),d0
		bclr.l	d1,d0
		move.l	d0,Mode(a4)
		move.l	a1,3(a0)
		bra.s	.DoMode

.IncVal:
		subq.w	#1,CounterDelay(a4)
		tst.w	CounterDelay(a4)
		bne	_MainLoop
		move.w	#10,CounterDelay(a4)

		move.l	3(a0),a1
		move.w	#0999,d0
.DoInc:		cmp.w	(a1),d0
		bgt.s	.IncOk
		clr.w	(a1)
		bra.s	.DoMode
.IncOk:		add.w	#0001,(a1)
		bra.s	.DoMode

*-------------- Is it "Start Game" ?

.ModeOn:	cmp.w	#9,Option(a4)
		bne.s	.Cont
		rts

.Cont:		lea	On.Msg(pc),a1
		lea	TogglesText(pc),a0

		clr.l	d1
		clr.l	d2	
		move.w	Option(a4),d1
		cmp.w	#7,d1			; is it blank?
		bgt.w	_MainLoop

		move.w	d1,d2
		mulu.w	#7,d2
		add.w	d2,a0
	
		tst.b	2(a0)
		bne.s	.DecVal
	
		move.l	Mode(a4),d0
		bset.l	d1,d0
		move.l	d0,Mode(a4)
		move.l	a1,3(a0)

.DoMode:	lea	TogglesText(pc),a6
		bsr	_PrintToggles
		bra.w	_MainLoop

.DecVal:
		subq.w	#1,CounterDelay(a4)
		tst.w	CounterDelay(a4)
		bne	_MainLoop
		move.w	#10,CounterDelay(a4)

		move.l	3(a0),a1
		tst.w	(a1)
		bne.s	.DecOk
		move.w	#0999,d0
.DoDec:		move.w	d0,(a1)
.DecOk:		sub.w	#0001,(a1)
		bra.s	.DoMode
*****************************************************************************
*-------------- Set all the toggles to display OFF!
*-------------- Unless the type is set to counter, then fill from the
*-------------- counter table!

*****************************************************************************
_InitTogs:	lea	TogglesText(pc),a0
		lea	Off.Msg(pc),a1
		lea	CounterPtr(a4),a2
.Loop:		tst.b	2(a0)
		bne.s	.Counter
.OnOff:		move.l	a1,3(a0)		; Off.Msg ptr
.Next:		addq.w	#7,a0			; table entry length
		cmp.b	#$ff,(a0)
		bne.s	.Loop
		rts
.Counter:	move.l	a2,3(a0)
		add.l	#2,a2			; get to the next counter val
		bra.s	.Next
*****************************************************************************
*-------------- A nice smooth scroller in a level 3.

_MyLevel3:	movem.l	d0-d7/a0-a6,-(sp)
		IFNE	Scroller
		bsr	_Scroller
		ENDC
		IFNE	Info
		bsr	_DoInfoText
		ENDC
		movem.l	(sp)+,d0-d7/a0-a6
		move.w	#$20,$dff09c		; clear request
		rte
*****************************************************************************
_DoInfoText:	tst.w	FadeInfo(a4)
		bne.s	.FadeIn			; -1
		beq.s	.FadeOut		; 0
.Exit:		rts

.FadeIn:	subq.w	#1,FadeDelay(a4)
		tst.w	FadeDelay(a4)
		bne.s	.Exit
		move.w	#5,FadeDelay(a4)

		lea	_Info_Color+2(pc),a0
		cmp.w	#$ddd,(a0)
		beq.s	.StoreA
		addi.w	#$111,(a0)
		rts
.StoreA:	clr.w	FadeInfo(a4)
		rts

.FadeOut:	subq.w	#1,FadeDelay(a4)
		tst.w	FadeDelay(a4)
		bne.s	.Exit
		move.w	#5,FadeDelay(a4)

		lea	_Info_Color+2(pc),a0
		tst.w	(a0)
		beq.s	.StoreB
		sub.w	#$111,(a0)
		rts
.StoreB:	move.w	#-1,FadeInfo(a4)
		jsr	_PrintInfo(pc)
		rts
*****************************************************************************
*-------------- Turn bar off.  Wipe the menu plane and display the keys.

_DoKeysText:	IFNE	Keys
		lea	BarTop(pc),a0
		move.w	#$0eee,6(a0)
		bsr	_WipeMenu

		bsr	VBLWAIT
		lea	KeysText(pc),a0
		bsr	_PrintLines

.lmb:		bsr	VBLWAIT
		btst	#6,$bfe001
		bne.s	.lmb
		ENDC
		rts
*****************************************************************************
*-------------- Turn bar off.  Wipe the menu plane and display thr keys.

_DoBbsText:	IFNE	BbsNums
		lea	BarTop(pc),a0
		move.w	#$0eee,6(a0)
		bsr	_WipeMenu

		bsr	VBLWAIT
		lea	BbsText(pc),a0
		bsr	_PrintLines

.rmb:		bsr	VBLWAIT
		btst	#$0a,$dff016
		bne.s	.rmb
		ENDC
		rts
********************************************************************************
*-------------- Wipe the menu screen by simply lsr each byte 8 times!

_WipeMenu:	moveq.l	#1,d2			; shift counter
.Lopy		bsr	VBLWAIT
		bsr	.Wipe
		addi.w	#1,d2
		cmpi.w	#8-1,d2
		bne.s	.Lopy
		rts
.Wipe		move.l	MenuPtr(a4),a0
		add.l	#MenuWidth*22,a0
		move.l	#(MenuSize-(MenuWidth*22))-1,d7
		subi.l	#1,d7
.Loop		move.b	(a0),d0
		lsr.b	d2,d0
		move.b	d0,(a0)+
		dbra	d7,.Loop
		rts	
*****************************************************************************
*-------------- Compare the new mouse position with the old.

_ReadMouse:	move.w	Mouse_Y(a4),d5

		move.w	MouseControl(a4),d1
		move.w	joy0dat(a5),d0
		move.w	d0,MouseControl(a4)

		move.w	d0,d2
		and.w	#$ff00,d2	; get y
		divu.w	#$100,d2
		move.w	d1,d3
		and.w	#$ff00,d3
		divu.w	#$100,d3
		sub.w	d3,d2		; get delta y
		move.w	d2,Mouse_DY(a4)

		move.w	Mouse_DX(a4),d0
		add.w	d0,Mouse_X(a4)
		move.w	Mouse_DY(a4),d0
		add.w	d0,Mouse_Y(a4)

		move.w	Mouse_Y(a4),d4
		sub.w	d5,d4
		bhi.s	_BarDown
		bmi.s	_BarUp
		rts

*-------------- Move the copper bar up 8 lines.

_BarUp:		tst.w	Option(a4)
		beq.s	.Exit
		subq.w	#1,Option(a4)
		lea	BarTop(pc),a0
		lea	BarBot(pc),a1
		subq.b	#$08,(a0)
		subq.b	#$08,(a1)
.Exit:		rts

*-------------- Move the copper bar down 8 lines.

_BarDown:	cmp.w	#9,Option(a4)
		beq.s	.Exit
		addq.w	#1,Option(a4)
		lea	BarTop(pc),a0
		lea	BarBot(pc),a1
		addq.b	#$08,(a0)
		addq.b	#$08,(a1)
.Exit		rts
*****************************************************************************
* PrintToggles()                                                            *
* ------------------------------------------------------------------------- *
*                                                                           *
* $Inputs:	a6:	ptr to the char$ string.                            *
*                                                                           *
*****************************************************************************
_PrintToggles:	move.l	MenuPtr(a4),a1
		add.l	#MenuWidth*4,a1
		clr.l	d0
		clr.l	d1
		clr.l	d2
		move.b	(a6)+,d0		; x
		move.b	(a6)+,d1		; y
		move.b	(a6)+,d2		; type
		tst.b	d2
		beq.s	.OnOff

		movem.l	d0-d2/a1,-(sp)

		move.l	(a6)+,a0
		clr.l	d1
		move.w	(a0),d1
		lea	WordBuffer(a4),a0
		bsr	_DecW2Ascii
		clr.w	(a0)			; null terminate
		lea	WordBuffer(a4),a0
		addq.l	#1,a0			; skip the 1st of 4 digits

		movem.l	(sp)+,d0-d2/a1

		bra.s	.Cont
.OnOff:		move.l	(a6)+,a0
.Cont:		mulu	#MenuWidth*8,d1
		mulu	#2,d0
		add.l	d1,d0
		add.l	d0,a1
		moveq.l	#0,d3
		moveq.l	#' ',d4
		moveq.l	#3,d5
.Loop:		move.l	d3,d2			; clear register
		move.b	(a0)+,d2		; get next char
		beq.s	.Exit			; yes, then rts
		sub.l	d4,d2			; adjust ASCII to actual
		asl.l	d5,d2			; x8 to get offset to data
		lea	TextFont(pc),a2		; a2 = character set data
		lea	0(a2,d2),a2		; a2 = data for this char
		move.b	(a2)+,(a1)		; 1st line of char
		move.b	(a2)+,80(a1)		; 2nd line of char
		move.b	(a2)+,160(a1)		; 3rd line of char
		move.b	(a2)+,240(a1)		; 4th line of char
		move.b	(a2)+,320(a1)		; 5th line of char
		move.b	(a2)+,400(a1)		; 6th line of char
		move.b	(a2)+,480(a1)		; 7th line of char
		move.b	(a2)+,560(a1)		; last line of char
		lea	1(a1),a1		; bump to next screen pos
		bra.s	.Loop
.Exit:		cmp.b	#$ff,(a6)
		bne.w	_PrintToggles
		rts
*****************************************************************************
_DecW2Ascii:	divu	#1000,d1
		bsr	.Digit
		divu	#100,d1
		bsr	.Digit
		divu	#10,d1
		bsr	.Digit
.Digit		add	#$30,d1
		move.b	d1,(a0)+
		clr	d1
		swap	d1
		rts
*****************************************************************************
_GetMem:	move.l	#MenuSize,d0
		move.l	#$10002,d1
		move.l	$4.w,a6
		jsr	-198(a6)
		move.l	d0,MenuPtr(a4)
		beq.w	_Error

		move.l	#ScrollerSize,d0
		move.l	#$10002,d1
		move.l	$4.w,a6
		jsr	-198(a6)
		move.l	d0,ScrollerPtr(a4)
		beq.w	_Error

		move.l	#InfoSize,d0
		move.l	#$10002,d1
		move.l	$4.w,a6
		jsr	-198(a6)
		move.l	d0,InfoPtr(a4)
		beq.w	_Error
		rts
*****************************************************************************
_FreeMem:	move.l	#MenuSize,d0
		move.l	MenuPtr(a4),a1
		move.l	$4.w,a6
		jsr	-210(a6)

		move.l	#ScrollerSize,d0
		move.l	ScrollerPtr(a4),a1
		move.l	$4.w,a6
		jsr	-210(a6)

		move.l	#InfoSize,d0
		move.l	InfoPtr(a4),a1
		move.l	$4.w,a6
		jsr	-210(a6)
		rts
*****************************************************************************
* PrintLines()                                                              *
* ------------------------------------------------------------------------- *
*                                                                           *
* $Inputs:	a0:	ptr to the char$ string.                            *
* $Outputs:	none.                                                       *
*                                                                           *
*****************************************************************************
_PrintLines:	move.l	MenuPtr(a4),a1
		add.l	#MenuWidth*4,a1
		clr.l	d0
		clr.l	d1
		move.b	(a0)+,d0		; x
		move.b	(a0)+,d1		; y
		mulu	#MenuWidth*8,d1
		add.l	d1,d0
		add.l	d0,a1

		moveq.l	#0,d3
		moveq.l	#' ',d4
		moveq.l	#3,d5
.Loop:		clr.l	d0
		move.l	d3,d2			; clear register
		move.b	(a0)+,d2		; get next char
		beq.s	.Exit			; yes, then rts
		sub.l	d4,d2			; adjust ASCII to actual
		asl.l	d5,d2			; x8 to get offset to data
		lea	TextFont(pc),a3		; a2 = character set data
		lea	0(a3,d2),a3		; a2 = data for this char

		move.b	(a3)+,(a1)		; 1st line of char
		move.b	(a3)+,80(a1)		; 2nd line of char
		move.b	(a3)+,160(a1)		; 3rd line of char
		move.b	(a3)+,240(a1)		; 4th line of char
		move.b	(a3)+,320(a1)		; 5th line of char
		move.b	(a3)+,400(a1)		; 6th line of char
		move.b	(a3)+,480(a1)		; 7th line of char
		move.b	(a3)+,560(a1)		; last line of char

		lea	1(a1),a1		; bump to next screen pos
		bra.s	.Loop
.Exit		cmp.b	#$ff,(a0)
		bne.b	_PrintLines
		rts
*****************************************************************************
_PrintInfo:	move.l	InfoTextPtr(a4),a0
		move.l	InfoPtr(a4),a1

		move.l	a1,a2
		move.w	#InfoSize-1,d7
.clr		clr.b	(a2)+
		dbra	d7,.clr

		clr.l	d0
		move.b	(a0)+,d0		; x
		mulu	#2,d0
		add.l	d0,a1

		moveq.l	#0,d3
		moveq.l	#' ',d4
		moveq.l	#3,d5
.Loop:		clr.l	d0
		move.l	d3,d2			; clear register
		move.b	(a0)+,d2		; get next char
		beq.s	.Exit			; yes, then rts
		sub.l	d4,d2			; adjust ASCII to actual
		asl.l	d5,d2			; x8 to get offset to data
		lea	TextFont(pc),a3		; a2 = character set data
		lea	0(a3,d2),a3		; a2 = data for this char

		move.b	(a3)+,(a1)		; 1st line of char
		move.b	(a3)+,80(a1)		; 2nd line of char
		move.b	(a3)+,160(a1)		; 3rd line of char
		move.b	(a3)+,240(a1)		; 4th line of char
		move.b	(a3)+,320(a1)		; 5th line of char
		move.b	(a3)+,400(a1)		; 6th line of char
		move.b	(a3)+,480(a1)		; 7th line of char
		move.b	(a3)+,560(a1)		; last line of char

		lea	1(a1),a1		; bump to next screen pos
		bra.s	.Loop
.Exit		cmp.b	#$ff,(a0)
		beq.s	.Reset
		move.l	a0,InfoTextPtr(a4)
		rts
.Reset:		lea	InfoText(pc),a0
		move.l	a0,InfoTextPtr(a4)
		rts
*****************************************************************************
_Scroller:	tst.w	ScrollerPause(a4)
		beq.s	.Continue
		subq.w	#1,ScrollerPause(a4)
		rts
.Continue:	move.l	ScrollerPtr(a4),a1
		move.l	a1,a0
		addq.l	#2,a0			; subtract 16 pixels
		jsr	BLITWAIT(pc)
		move.l	a0,bltApth(a5)		; source
		move.l	a1,bltDpth(a5)		; destination
		move.l  #$e9f00000,bltcon0(a5)	; A = D, 8 bit shift
		move.l  #$00000000,bltAmod(a5)	; mod
		move.l	#$ffffffff,bltafwm(a5)	; masks
		move.w	#(12*64)+51,bltsize(a5)
		subq.w	#1,ScrollerDelay(a4)	; need new character?
		beq.s	.GetChar		; if zero branch
		rts				; else return
.GetChar:	move.w  #4,ScrollerDelay(a4)	; new char delay
		addq.w	#1,ScrollerPos(a4)		; next scroller character

.Again:		lea	ScrollerText(pc),a0
		add.w	ScrollerPos(a4),a0
		
		move.l	ScrollerPtr(a4),a1
		add.l	#90,a1

.PrintChar:	clr.l	d0			; clear what character

		move.b	(a0),d0			; get byte of text
		beq.s	.Reset
		cmp.b	#Pause,d0
		bne.s	.Continue1
		clr.l	d0
		move.b	1(a0),d0
		ext.w	d0
		move.w	d0,ScrollerPause(a4)
		addq.w	#2,ScrollerPos(a4)
		rts
.Continue1:	sub.b	#32,d0			; find character
		mulu	#8,d0			; find offset
		lea	TextFont(pc),a2		; find font address
		add.l	d0,a2			; find actual font address
		moveq	#8-1,d2			; how many bytes to copy 1-1
		move.l	a1,a3			; store address
.DoChar:	move.b	(a2)+,(a3)		; move byte
		add.l	#ScrollerWidth-2,a3	; next line
		dbra	d2,.DoChar		; is character finished ?
		rts
.Reset:		clr.w	ScrollerPos(a4)
		move.l	ScrollerPtr(a4),a0
		move.w	#(ScrollerSize/4)-1,d7
.Clr:		clr.l	(a0)+
		dbra	d7,.Clr
		rts
*******************************************************************************
BLITWAIT:	tst.b	$dff002
.bw:		btst	#6,$dff002		;Blitwait macro...
		bne.s	.bw			;Wait for blitter to stop
		rts
*****************************************************************************
VBLWAIT:	cmpi.b	#255,$dff006		; is vhposr = 255
		bne.s	VBLWAIT			; no, then loop
		rts
*******************************************************************************
*-------------- Just init my custom copper list.

_InitCopper:	lea	_MyCopper(pc),a0
		move.l	a0,cop1lch(a5)		; install my copperlist.
		clr.w	copjmp1(a5)
		rts				; done.
*******************************************************************************
_InitPlanes:	IFNE	Logo
		move.l	LogoPtr(a4),a0
		move.l	a0,d0
		lea	_Logo_Ptrs(pc),a0	; a0 = plane ptr's in copper
		moveq	#LogoDepth-1,d1		; d1 = number planes-1
.LogoLoop:	move.w	d0,6(a0)		; load low word
		swap	d0			; swap words
		move.w	d0,2(a0)		; load high word
		swap	d0			; swap words
		add.l	#LogoWidth*LogoHeight,d0
		addq.l	#8,a0			; next plane ptr in copper
		dbra	d1,.LogoLoop  		; finished ?
		ENDC

		move.l	MenuPtr(a4),a0
		add.l	#MenuWidth,a0
		move.l	a0,d0
		lea	_Menu_Ptrs(pc),a0	; a0 = plane ptr's in copper
		move.w	d0,6(a0)		; load low word
		swap	d0			; swap words
		move.w	d0,2(a0)		; load high word
		swap	d0			; swap words
		addq.l	#8,a0			; next plane ptr in copper
		sub.l	#MenuWidth,d0
		move.w	d0,6(a0)		; load low word
		swap	d0			; swap words
		move.w	d0,2(a0)		; load high word

		move.l	ScrollerPtr(a4),a0
		move.l	a0,d0
		lea	_Scroller_Ptrs(pc),a0	; a0 = plane ptr's in copper
		move.w	d0,6(a0)		; load low word
		swap	d0			; swap words
		move.w	d0,2(a0)		; load high word

		move.l	InfoPtr(a4),a0
		move.l	a0,d0
		lea	_Info_Ptrs(pc),a0	; a0 = plane ptr's in copper
		move.w	d0,6(a0)		; load low word
		swap	d0			; swap words
		move.w	d0,2(a0)		; load high word
		rts
*******************************************************************************
*-------------- Set all the sprite pointers to a null sprite, just to
*-------------- stop any screen crap!

_InitSprites:	lea	_Sprite_Ptrs(pc),a0
		lea	NullSprite(a4),a1
		move.w	(a1),d0
		move.w	d0,6(a0)
		move.w	d0,14(a0)
		move.w	d0,22(a0)
		move.w	d0,30(a0)
		move.w	d0,38(a0)
		move.w	d0,46(a0)
		move.w	d0,54(a0)
		swap	d0
		move.w	d0,2(a0)
		move.w	d0,10(a0)
		move.w	d0,18(a0)
		move.w	d0,26(a0)
		move.w	d0,34(a0)
		move.w	d0,42(a0)
		move.w	d0,50(a0)
		move.w	d0,58(a0)
		rts
********************************************************************************
		cnop	0,4
_MyCopper:	dc.w	$0a07,$fffe			; wait for line 10
_Sprite_Ptrs:	dc.w	spr0pth,$0000,spr0ptl,$0000	; clear the sprites
		dc.w	spr1pth,$0000,spr1ptl,$0000	; so there is no screen crap
		dc.w	spr2pth,$0000,spr2ptl,$0000
		dc.w	spr3pth,$0000,spr3ptl,$0000
		dc.w	spr4pth,$0000,spr4ptl,$0000
		dc.w	spr5pth,$0000,spr5ptl,$0000
		dc.w	spr6pth,$0000,spr6ptl,$0000
		dc.w	spr7pth,$0000,spr7ptl,$0000

		dc.w	diwstrt,$2c81,diwstop,$2cc1
		dc.w	ddfstrt,$0038,ddfstop,$00d0
		dc.w	bpl1mod,$0000,bpl2mod,$0000
		dc.w	bplcon0,$0000
		dc.w	bplcon1,$0000
		dc.w	bplcon2,$0000

		IFNE	Logo
		dc.w	bplcon0,$4200
_Logo_Ptrs:	dc.w	bpl1pth,$0000,bpl1ptl,$0000
		dc.w	bpl2pth,$0000,bpl2ptl,$0000
		dc.w	bpl3pth,$0000,bpl3ptl,$0000
		dc.w	bpl4pth,$0000,bpl4ptl,$0000

		dc.w	$0180,$0000,$0182,$0eee,$0184,$0eea,$0186,$0ee0
		dc.w	$0188,$0db0,$018a,$0d90,$018c,$0c80,$018e,$0a60
		dc.w	$0190,$0840,$0192,$0620,$0194,$0720,$0196,$0830
		dc.w	$0198,$0950,$019a,$0b60,$019c,$0c70,$019e,$0d90
		ENDC
*- Top bar
		dc.w	$6007,$fffe,color00,$0aac
		dc.w	ddfstrt,$003c,ddfstop,$00d4
		dc.w	bplcon0,$a200			; 2p hi-res
		dc.w	bplcon1,$0010
_Menu_Ptrs:	dc.w	bpl1pth,$0000,bpl1ptl,$0000
		dc.w	bpl2pth,$0000,bpl2ptl,$0000
		dc.w	color01,$0eee,color02,$0437,color03,$0eee
		dc.w	$6207,$fffe,color00,$088a
		dc.w	$7407,$fffe,color00,$0668
		dc.w	$7607,$fffe,color00,$0000

*- Mid section

		dc.w	$7807,$fffe,color00,$098c
		dc.w	$7a07,$fffe,color00,$0769

BarTop:		dc.w	$8307,$fffe,color01,$0999,color03,$0999
BarBot:		dc.w	$8b07,$fffe,color01,$0eee,color03,$0eee

		dc.w	$e607,$fffe,color00,$0437
		dc.w	$e807,$fffe,color00,$0000

*- Bottom bar
		dc.w	$ea07,$fffe,color00,$066c,color01,$0eee
		dc.w	$ec07,$fffe,color00,$044a
		dc.w	$ed07,$fffe
		dc.w	diwstrt,$2c51,diwstop,$2cd1
		dc.w	ddfstrt,$0028,ddfstop,$00d8
		dc.w	bpl1mod,$0008,bpl2mod,$0008
		dc.w	bplcon0,$9200			; 1p hi-res
		dc.w	bplcon1,$0000
_Scroller_Ptrs:	dc.w	bpl1pth,$0000,bpl1ptl,$0000
		dc.w	$f407,$fffe,color00,$0228
		dc.w	$f607,$fffe,color00,$0000
		dc.w	bplcon0,$0200
*- info text
		dc.w	$ffdf,$fffe
		dc.w	$0d07,$fffe,color00,$0000,color01,$0eee
		dc.w	ddfstrt,$003c,ddfstop,$00d4
		dc.w	diwstrt,$2c81,diwstop,$2cc1
		dc.w	bpl1mod,$0000,bpl2mod,$0000
		dc.w	bplcon0,$9200			; 1p hi-res
_Info_Ptrs:	dc.w	bpl1pth,$0000,bpl1ptl,$0000
_Info_Color	dc.w	color01,$0000
		dc.w	$1d07,$fffe,bplcon0,$0200
		dc.w	$ffff,$fffe
		dc.w	$ffff,$fffe
*******************************************************************************
TextFont:	incbin	HF:bins/Font.8x8
		IFNE	Logo
LogoBin:	incbin	HF:Bins/Logo.320x52x4.bm
		ENDC
*******************************************************************************
*-------------- 85 characters displayed on screen at one time!

Pause		=	$ff
		cnop	0,4
ScrollerText:	dc.b	" "
		dc.b	"- H E L L F I R E -"
		dc.b	"                                 ",Pause,50 ;33
		dc.b	"                                 "	;33
		dc.b	"Presents Another Trainer."
		dc.b	"                             ",Pause,50
		dc.b	"                                 "	;33
		dc.b	"Speris Legacy +16 "
		dc.b	"                                 ",Pause,50 ;33
		dc.b	" Greetings To All These Great Guys: "
		dc.b	"LaZZeR, Cyanide, 2-Cool, Iggy, Axen, MDR, Rebel, "
		dc.b	"Thrash, Ooh and not forgetting Galahad, "
		dc.b	"Heat, Conan & Newton/C&N."
		dc.b	"                                        "
		dc.b	"Special Greetings To All Hard-Working Trainers Out There!      "
		dc.b	"Don't Let The Fun And Good Work Die..      "
		dc.b	"Regards Fly Out From HF To The Followin Groups For Their "
		dc.b	"Part In Keeping The Amiga Alive -: "
		dc.b	"ANTHROX, CRUX, DELIGHT, FAiRLiGHT, LSD, PRESTiGE, PRODIGY, QUARTEX. "
		dc.b	"                                         "
		dc.b	"                                         "
		dc.b	"Remember, Training Is An Art NOT A Race!!"
		dc.b	"                       "
		dc.b	Pause,50
		dc.b	"                                         "
		dc.b	"                                       "
		dc.b	"HELLFIRE - WE ARE MORE THAN NEWCOMERS!"
		dc.b	"                        "
		dc.b	Pause,100
		dc.b	"                                    "
		dc.b	"                     TEXT RESTARTS "
		dc.b	"                                    "
		dc.b	"                                    ",0
********************************************************************************
InfoText:	dc.b	14,"Menu Coding by: Beldin",0
		dc.b	14,"  Trained by: Beldin",0
		IFNE	Logo
		dc.b	14," Logo by: Hudson Hawk",0
		ENDC
		dc.b	$ff	
		even
		IFNE	BbsNums
BbsText:	dc.b	05,04,"              -*- CALL OUR QUALITY BOARDS WORLDWIDE! -*-",0
		dc.b	05,05,"+--------------------------------------------------------------------+",0
		dc.b	05,06,"|             BOONDOCKS         [WHQ!]  +31-ELITE!-ONLY!             |",0
		dc.b	05,07,"|             SKYTOWER          [EHQ!]  +45-ELiTE-ONLY!!             |",0
		dc.b	05,08,"|             TEMPLE OF DREAMS  [UHQ!]  +4X-TRY-TO-FIND!             |",0
		dc.b	05,09,"|             ACID SLAM         [GHQ!]  +49-ELITE!-ONLY!             |",0
		dc.b	05,10,"|             ELECTRIC WARRIOR  [UKHQ]  +41-ITS-PRIVATE!             |",0
		dc.b	05,11,"|             FREEDOM WITHIN    [UKHQ]  +41-ELITE-KNOWS!             |",0
		dc.b	05,12,"|             CEMENT CITY       [EHQ!]  +41-TRY-TO-FIND!             |",0
		dc.b	05,13,"|             ON THE RUN        [GHQ!]  +49-ITS-PRIVATE!             |",0
		dc.b	05,14,"|             EXTREME TERROR    [DIST]  +49-ELITE!-ONLY!             |",0
		dc.b	05,15,"+--------------------------------------------------------------------+  RMB",0
		dc.b	$ff
		even
		ENDC
HeadingText:	dc.b	22,0
		dc.b	"-*- SPERIS LEGACY - +16 Trainer -*-",0
		dc.b	24,1
		dc.b	"Trained by:  Beldin of Hellfire",0
MenuText:	dc.b	24,4
		dc.b	"Unlimited Lives",0
		dc.b	24,5
		dc.b	"Unlimited Armour",0
		dc.b	24,6
		dc.b	"Invulnerability",0
		dc.b	24,7
		dc.b	"Unlimited Fuel",0
		dc.b	24,8
		dc.b	"Unlimited Cannons",0
		dc.b	24,9
		dc.b	"Unlimited Rockets",0
		dc.b	24,10
		dc.b	"Unlimited AAM's",0
		dc.b	24,11
		dc.b	"In-Game Keys",0
		dc.b	31,13
		dc.b	"!START THE GAME!",0
		dc.b	18,15
		dc.b	"* HELLFIRE - WE ARE MORE THAN NEWCOMERS! *",0
		dc.b	$ff
		even

*- Please note: You only have to set the type to 1 4 the counter 2 b active!
*-                      x, y, type 0=on/off 1=counter

TogglesText:	dc.b	26,04,0
		ds.l	1		; ptr to label 4 counter
		dc.b	26,05,0
		ds.l	1
		dc.b	26,06,0
		ds.l	1
		dc.b	26,07,0
		ds.l	1
		dc.b	26,08,0
		ds.l	1
		dc.b	26,09,0
		ds.l	1
		dc.b	26,10,0
		ds.l	1
		dc.b	26,11,0
		ds.l	1
		dc.b	$ff
		even
On.Msg:		dc.b	"ON ",0
Off.Msg:	dc.b	"OFF",0
		even
		IFNE	Keys
KeysText:	dc.b	00,04
		dc.b	"                     -*-  Try These Keys During Play!  -*-",0
		dc.b	05,06
		dc.b	"+--------------------------------------------------------------------+",0
		dc.b	05,07
		dc.b	"|       (F1) - Add 25 Cannons           (L) - Toggle Lives           |",0
		dc.b	05,08
		dc.b	"|       (F2) - Add 25 Rockets           (A) - Toggle Armour          |",0
		dc.b	05,09
		dc.b	"|       (F3) - Add 25 AAM's             (I) - Toggle Invulnerability |",0
		dc.b	05,10
		dc.b	"|       (F4) - Add 500 Money            (F) - Toggle Fuel            |",0
		dc.b	05,11
		dc.b	"|     (HELP) - Skip Mission             (W) - Toggle All Weapons     |",0
		dc.b	05,12
		dc.b	"|        (Z) - Toggle Collision Detection (See Text)                 |",0
		dc.b	05,13
		dc.b	"+--------------------------------------------------------------------+  LMB",0
		dc.b	$ff
		even
		ENDC
_End:

		END
