	machine	68020

	incdir	"!includes:OS3.0"
	include	"exec/types.i"
	include	"exec/execbase.i"
	include	"intuition/intuition.i"
	include	"libraries/gadtools.i"
	include	"libraries/reqtools.i"
	include	"dos/dos.i"

	include	"workbench/workbench.i"
	include	"workbench/startup.i"

	incdir	"!includes:"
	include	"LVO/exec_lib.i"
	include	"LVO/intuition_lib.i"
	include	"LVO/gadtools_lib.i"
	include	"LVO/graphics_lib.i"
	include	"LVO/reqtools_lib.i"
	include	"LVO/dos_lib.i"


	incdir	""
	include	"SNES.i"

	include	"code/SNES_gui.i"

_SysBase		=	$4.w

	section	code,code

prg_Init

	* check if program was started from wb

	move.l	(4).w,a6
	sub.l	a1,a1
	jsr	_LVOFindTask(a6)
	move.l	d0,ptr_ThisTask

	move.l	ptr_ThisTask,a4
	tst.l	pr_CLI(a4)
	bne	.StartedFromCLI

	* fetch wb message

	lea.l	pr_MsgPort(a4),a0
	jsr	_LVOWaitPort(a6)
	lea.l	pr_MsgPort(a4),a0
	jsr	_LVOGetMsg(a6)
	move.l	d0,ptr_StartupMessage

.StartedFromCLI

	* check if cpu is minimum 020

	move.l	(4).w,a6
	move.w	AttnFlags(a6),d0
	btst.w	#AFB_68020,d0
	beq	prg_Err

	* open libraries

	move.l	_SysBase,a6

	lea.l	_GfxName,a1
	move.l	#39,d0
	jsr	_LVOOpenLibrary(a6)
	move.l	d0,_GfxBase
	beq	prg_Err

	lea.l	_IntuitionName,a1
	move.l	#39,d0
	jsr	_LVOOpenLibrary(a6)
	move.l	d0,_IntuitionBase
	beq	prg_Err

	lea.l	_GadToolsName,a1
	move.l	#39,d0
	jsr	_LVOOpenLibrary(a6)
	move.l	d0,_GadToolsBase
	beq	prg_Err

	lea.l	_ReqToolsName,a1
	move.l	#38,d0
	jsr	_LVOOpenLibrary(a6)
	move.l	d0,_ReqToolsBase
	beq	prg_Err

	lea.l	_DosName,a1
	move.l	#39,d0
	jsr	_LVOOpenLibrary(a6)
	move.l	d0,_DosBase
	beq	prg_Err

	move.l	_ReqToolsBase,a6
	move.l	#RT_FILEREQ,d0
	sub.l	a0,a0
	jsr	_LVOrtAllocRequestA(a6)
	move.l	d0,ptr_FileRequester
	beq	prg_Err

	* poll current path

	tst.l	ptr_StartupMessage
	beq	.no_dir_waiting

	move.l	_DosBase,a6
	move.l	ptr_StartupMessage,a2
	move.l	sm_ArgList(a2),a2
	move.l	wa_Lock(a2),d1
	jsr	_LVOCurrentDir(a6)

.no_dir_waiting

	* set default configuration

	lea.l	prg_ConfigBuffer,a0
	move.l	#1,CFG_ROMForce(a0)
	move.l	#0,CFG_CyberGFX(a0)
	move.l	#0,CFG_DirectWrite(a0)
	move.l	#100,CFG_Speed(a0)
	move.l	#0,CFG_FrameSkip(a0)	
	move.l	#0,CFG_DisplayID(a0)
	move.l	#0,CFG_ForceReset(a0)
	move.l	#1,CFG_FastVBL(a0)

	* load configuration

	move.l	_DosBase,a6
	move.l	#prg_ConfigName,d1
	move.l	#MODE_OLDFILE,d2
	jsr	_LVOOpen(a6)
	move.l	d0,a4
	tst.l	d0
	beq	.skip_load

	move.l	a4,d1
	move.l	#prg_ConfigBuffer,d2
	move.l	#CFG_SIZEOF,d3
	jsr	_LVORead(a6)

	move.l	a4,d1
	jsr	_LVOClose(a6)

.skip_load

	* set current path in requester

	move.l	_ReqToolsBase,a6
	move.l	ptr_FileRequester,a1
	lea.l	prg_CurrDirReq,a0
	jsr	_LVOrtChangeReqAttrA(a6)

	* open gui

	jsr	SetupScreen
	tst.l	d0
	bne	prg_Err

	jsr	OpenSNESMenuWindow
	tst.l	d0
	bne	prg_Err

	* blit logo

	move.l	_GfxBase,a6
	lea.l	prg_SNESLogoBitmap,a0
	move.l	#0,d0
	move.l	#0,d1
	move.l	SNESMenuWnd,a1
	move.b	wd_BorderLeft(a1),d2
	extb.l	d2
	move.b	wd_BorderTop(a1),d3
	extb.l	d3
	add.l	#4,d2
	add.l	#23,d3

	move.l	wd_RPort(a1),a1

	move.l	#300,d4
	move.l	#72,d5
	move.l	#$c0,d6
	jsr	_LVOBltBitMapRastPort(a6)

prg_Menu

	move.l	_SysBase,a6		;put sysbase in a6
	move.l	SNESMenuWnd,a0		;get ptr to memory-display window
	move.l	wd_UserPort(a0),a0	;get window userport
	jsr	_LVOWaitPort(a6)	;wait for messages

.msg_loop

	move.l	_GadToolsBase,a6	;put gadtoolsbase in a6
	move.l	SNESMenuWnd,a0		;get ptr to memory-display window
	move.l	wd_UserPort(a0),a0	;get window userport
	jsr	_LVOGT_GetIMsg(a6)	;get any waiting message
	move.l	d0,ptr_Message		;store msg
	beq	.no_SNESMenuWnd		;if no message, continue looping

	move.l	ptr_Message,a4
	move.l	im_Class(a4),d4

	cmp.l	#IDCMP_GADGETUP,d4
	bne	.no_IDCMP_GADGETUP

	move.l	im_IAddress(a4),a3	;get ptr to gadget int a3
	move.w	gg_GadgetID(a3),d4	;get gadget id to d4

	cmp.w	#GDX_OpenROM,d4
	bne	.not_GDX_OpenROM

	lea.l	prg_FileNameBuffer,a0
	move.l	#2000,d0
	jsr	FSL_SelectLoadFile

	tst.l	d0
	beq	.no_file

	lea.l	prg_FileNameBuffer,a0
	lea.l	prg_ROMHeader,a1
	jsr	ROM_GetHeader

.no_file

	clr.l	d5

	lea.l	prg_ROMHeader,a1
	tst.l	RMH_HeaderValid(a1)
	seq.l	d5

	lea.l	prg_SNESMenuTags,a0
	move.l	d5,4(a0)

	move.l	_GadToolsBase,a6
	lea.l	SNESMenuGadgets+GD_StartEmulator*4,a0
	move.l	(a0),a0
	move.l	SNESMenuWnd,a1
	sub.l	a2,a2
	lea.l	prg_SNESMenuTags,a3
	jsr	_LVOGT_SetGadgetAttrsA(a6)

	move.l	_GadToolsBase,a6
	lea.l	SNESMenuGadgets+GD_ROMInfo*4,a0
	move.l	(a0),a0
	move.l	SNESMenuWnd,a1
	sub.l	a2,a2
	lea.l	prg_SNESMenuTags,a3
	jsr	_LVOGT_SetGadgetAttrsA(a6)

	clr.l	d4

.not_GDX_OpenROM

	cmp.w	#GDX_StartEmulator,d4
	bne	.not_GDX_StartEmulator

	jsr	_EmulateSNES

	clr.l	d4

.not_GDX_StartEmulator

	cmp.w	#GDX_ROMInfo,d4
	bne	.not_GDX_ROMInfo

	lea.l	prg_ROMHeader,a5

	tst.l	RMH_HeaderValid(a5)
	beq	.not_GDX_ROMInfo

	jsr	_ShowROMInfo

.not_GDX_ROMInfo

	cmp.w	#GDX_Preferences,d4
	bne	.not_GDX_Preferences

	jsr	OpenPrefsWindow
	tst.l	d0
	bne	.no_Prefs

	lea.l	prg_ConfigBuffer,a4

	* fetch preferences from buffer

	move.l	_GadToolsBase,a6
	lea.l	PrefsGadgets+GD_ForceMode*4,a0
	move.l	(a0),a0
	move.l	PrefsWnd,a1
	sub.l	a2,a2
	lea.l	prg_CycleTags,a3
	move.l	CFG_ROMForce(a4),4(a3)
	jsr	_LVOGT_SetGadgetAttrsA(a6)

	move.l	_GadToolsBase,a6
	lea.l	PrefsGadgets+GD_Speed*4,a0
	move.l	(a0),a0
	move.l	PrefsWnd,a1
	sub.l	a2,a2
	lea.l	prg_SlideTags,a3
	move.l	CFG_Speed(a4),4(a3)
	jsr	_LVOGT_SetGadgetAttrsA(a6)

	move.l	_GadToolsBase,a6
	lea.l	PrefsGadgets+GD_FrameSkip*4,a0
	move.l	(a0),a0
	move.l	PrefsWnd,a1
	sub.l	a2,a2
	lea.l	prg_SlideTags,a3
	move.l	CFG_FrameSkip(a4),4(a3)
	jsr	_LVOGT_SetGadgetAttrsA(a6)

	move.l	_GadToolsBase,a6
	lea.l	PrefsGadgets+GD_CyberGFX*4,a0
	move.l	(a0),a0
	move.l	PrefsWnd,a1
	sub.l	a2,a2
	lea.l	prg_CheckTags,a3
	move.l	CFG_CyberGFX(a4),4(a3)
	jsr	_LVOGT_SetGadgetAttrsA(a6)

	move.l	_GadToolsBase,a6
	lea.l	PrefsGadgets+GD_DirectWrite*4,a0
	move.l	(a0),a0
	move.l	PrefsWnd,a1
	sub.l	a2,a2
	lea.l	prg_CheckTags,a3
	move.l	CFG_DirectWrite(a4),4(a3)
	jsr	_LVOGT_SetGadgetAttrsA(a6)

	move.l	_GadToolsBase,a6
	lea.l	PrefsGadgets+GD_ForceReset*4,a0
	move.l	(a0),a0
	move.l	PrefsWnd,a1
	sub.l	a2,a2
	lea.l	prg_CheckTags,a3
	move.l	CFG_ForceReset(a4),4(a3)
	jsr	_LVOGT_SetGadgetAttrsA(a6)

	move.l	_GadToolsBase,a6
	lea.l	PrefsGadgets+GD_FastVBL*4,a0
	move.l	(a0),a0
	move.l	PrefsWnd,a1
	sub.l	a2,a2
	lea.l	prg_CheckTags,a3
	move.l	CFG_FastVBL(a4),4(a3)
	jsr	_LVOGT_SetGadgetAttrsA(a6)

	* wait for closegadget

.PrefsLoop

	clr.l	d6

	move.l	_SysBase,a6		;put sysbase in a6
	move.l	PrefsWnd,a0		;get ptr to memory-display window
	move.l	wd_UserPort(a0),a0	;get window userport
	jsr	_LVOWaitPort(a6)	;wait for messages

.Prefsmsg_loop

	move.l	_GadToolsBase,a6	;put gadtoolsbase in a6
	move.l	PrefsWnd,a0		;get ptr to memory-display window
	move.l	wd_UserPort(a0),a0	;get window userport
	jsr	_LVOGT_GetIMsg(a6)	;get any waiting message
	move.l	d0,ptr_Message		;store msg
	beq	.no_PrefsMsg		;if no message, continue looping

	move.l	ptr_Message,a4
	move.l	im_Class(a4),d4

	cmp.l	#IDCMP_GADGETUP,d4
	bne	.no_IDCMP_GADGETUP_config

	move.l	im_IAddress(a4),a4
	move.w	gg_GadgetID(a4),d4

	cmp.w	#GD_ScreenMode,d4
	bne	.not_screenmode

	lea.l	prg_ConfigBuffer,a4
	move.l	CFG_DisplayID(a4),d0
	jsr	prg_GetScreenMode
	lea.l	prg_ConfigBuffer,a4
	move.l	d0,CFG_DisplayID(a4)

.not_screenmode

	clr.l	d4

.no_IDCMP_GADGETUP_config

	cmp.l	#IDCMP_CLOSEWINDOW,d4
	seq.l	d6

	move.l	_GadToolsBase,a6	;put gadtoolsbase in a6
	move.l	ptr_Message,a1		;put tempmsg in a1
	jsr	_LVOGT_ReplyIMsg(a6)	;reply window msg

	bra	.Prefsmsg_loop

.no_PrefsMsg

	tst.l	d6
	beq	.PrefsLoop

	* store preferences

	lea.l	prg_ConfigBuffer,a4

	move.l	_GadToolsBase,a6
	lea.l	PrefsGadgets+GD_ForceMode*4,a0
	move.l	(a0),a0
	move.l	PrefsWnd,a1
	sub.l	a2,a2
	lea.l	prg_CycleTags,a3
	lea.l	CFG_ROMForce(a4),a5
	move.l	a5,4(a3)
	jsr	_LVOGT_GetGadgetAttrsA(a6)

	move.l	_GadToolsBase,a6
	lea.l	PrefsGadgets+GD_Speed*4,a0
	move.l	(a0),a0
	move.l	PrefsWnd,a1
	sub.l	a2,a2
	lea.l	prg_SlideTags,a3
	lea.l	CFG_Speed(a4),a5
	move.l	a5,4(a3)
	jsr	_LVOGT_GetGadgetAttrsA(a6)

	move.l	_GadToolsBase,a6
	lea.l	PrefsGadgets+GD_FrameSkip*4,a0
	move.l	(a0),a0
	move.l	PrefsWnd,a1
	sub.l	a2,a2
	lea.l	prg_SlideTags,a3
	lea.l	CFG_FrameSkip(a4),a5
	move.l	a5,4(a3)
	jsr	_LVOGT_GetGadgetAttrsA(a6)

	move.l	_GadToolsBase,a6
	lea.l	PrefsGadgets+GD_CyberGFX*4,a0
	move.l	(a0),a0
	move.l	PrefsWnd,a1
	sub.l	a2,a2
	lea.l	prg_CheckTags,a3
	lea.l	CFG_CyberGFX(a4),a5
	move.l	a5,4(a3)
	jsr	_LVOGT_GetGadgetAttrsA(a6)

	move.l	_GadToolsBase,a6
	lea.l	PrefsGadgets+GD_DirectWrite*4,a0
	move.l	(a0),a0
	move.l	PrefsWnd,a1
	sub.l	a2,a2
	lea.l	prg_CheckTags,a3
	lea.l	CFG_DirectWrite(a4),a5
	move.l	a5,4(a3)
	jsr	_LVOGT_GetGadgetAttrsA(a6)

	move.l	_GadToolsBase,a6
	lea.l	PrefsGadgets+GD_ForceReset*4,a0
	move.l	(a0),a0
	move.l	PrefsWnd,a1
	sub.l	a2,a2
	lea.l	prg_CheckTags,a3
	lea.l	CFG_ForceReset(a4),a5
	move.l	a5,4(a3)
	jsr	_LVOGT_GetGadgetAttrsA(a6)

	move.l	_GadToolsBase,a6
	lea.l	PrefsGadgets+GD_FastVBL*4,a0
	move.l	(a0),a0
	move.l	PrefsWnd,a1
	sub.l	a2,a2
	lea.l	prg_CheckTags,a3
	lea.l	CFG_FastVBL(a4),a5
	move.l	a5,4(a3)
	jsr	_LVOGT_GetGadgetAttrsA(a6)

.no_Prefs

	jsr	ClosePrefsWindow

	clr.l	d4

.not_GDX_Preferences

	cmp.w	#GDX_About,d4
	bne	.not_GDX_About

	jsr	_ShowAbout

	clr.l	d4

.not_GDX_About

	cmp.w	#GDX_Quit,d4
	bne	.not_GDX_Quit

	st.l	prg_Terminate

	clr.l	d4

.not_GDX_Quit

	clr.l	d4

.no_IDCMP_GADGETUP

	move.l	_GadToolsBase,a6	;put gadtoolsbase in a6
	move.l	ptr_Message,a1		;put tempmsg in a1
	jsr	_LVOGT_ReplyIMsg(a6)	;reply window msg

	bra	.msg_loop

.no_SNESMenuWnd

	tst.l	prg_Terminate
	beq	prg_Menu

prg_Closedown

	jsr	CloseSNESMenuWindow

	jsr	CloseDownScreen

	* save configuration

	move.l	ptr_FileRequester,a0
	move.l	rtfi_Dir(a0),a0
	lea.l	prg_ConfigBuffer,a1

.copystring
	move.b	(a0)+,(a1)+
	bne	.copystring

	move.l	_DosBase,a6

	move.l	#prg_ConfigName,d1
	move.l	#MODE_NEWFILE,d2
	jsr	_LVOOpen(a6)
	move.l	d0,a4
	tst.l	d0
	beq	.skip_save

	move.l	a4,d1
	move.l	#prg_ConfigBuffer,d2
	move.l	#CFG_SIZEOF,d3
	jsr	_LVOWrite(a6)

	move.l	a4,d1
	jsr	_LVOClose(a6)

.skip_save

	* close libraries

	tst.l	_DosBase
	beq	.no_dos

	move.l	_DosBase,a6

	move.l	a6,a1
	move.l	_SysBase,a6
	jsr	_LVOCloseLibrary(a6)

	move.l	#0,_DosBase

.no_dos

	tst.l	_ReqToolsBase
	beq	.no_asl

	move.l	_ReqToolsBase,a6

	move.l	ptr_FileRequester,a1
	tst.l	a1
	beq	.noRequester

	jsr	_LVOrtFreeRequest(a6)

.noRequester

	move.l	a6,a1
	move.l	_SysBase,a6
	jsr	_LVOCloseLibrary(a6)

	move.l	#0,_ReqToolsBase


.no_asl

	tst.l	_GadToolsBase
	beq	.no_gadtools

	move.l	_GadToolsBase,a6

	move.l	a6,a1
	move.l	_SysBase,a6
	jsr	_LVOCloseLibrary(a6)

	move.l	#0,_GadToolsBase


.no_gadtools

	tst.l	_IntuitionBase
	beq	.no_intuition

	move.l	_IntuitionBase,a6

	move.l	a6,a1
	move.l	_SysBase,a6
	jsr	_LVOCloseLibrary(a6)

	move.l	#0,_IntuitionBase


.no_intuition

	tst.l	_GfxBase
	beq	.no_graphics

	move.l	_GfxBase,a6

	move.l	a6,a1
	move.l	_SysBase,a6
	jsr	_LVOCloseLibrary(a6)

	move.l	#0,_GfxBase


.no_graphics

	tst.l	ptr_StartupMessage
	beq	.noWBMessage

	move.l	(4).w,a6
	jsr	_LVOForbid(a6)

	move.l	ptr_StartupMessage,a1
	jsr	_LVOReplyMsg(a6)

.noWBMessage

	move.l	prg_Error,d0
	rts

prg_Err
	move.l	#20,prg_Error
	bra	prg_Closedown

_ShowAbout
	movem.l	d0-a6,-(sp)

	lea.l	.WriteTable,a2

.WriteOut

	move.l	(a2)+,a0
	tst.l	a0
	beq	.AllOut

	jsr	_PrintInfo

	bra	.WriteOut

.AllOut

	movem.l	(sp)+,d0-a6
	rts

.WriteTable
		dc.l	.Title
		dc.l	.Empty
		dc.l	.Copyright
		dc.l	.Empty
		dc.l	.Freeware
		dc.l	.Empty
		dc.l	.Email
		dc.l	.Empty
		dc.l	0

.Title		dc.b	"Amiga SuperNES Emulator v0.13b",0
.Copyright	dc.b	"Copyright © 1997-1998 Jesper Svennevid",0
.Freeware	dc.b	"This program is freeware!",0
.Email		dc.b	"Send me an email: chip@ramses.ml.org",0

.Empty	dc.b	0

_ShowROMInfo
	movem.l	d0-a6,-(sp)

	lea.l	prg_ROMHeader,a5

	; ROM Title

	lea.l	.DataTable,a0
	move.l	#.ROMTitle,(a0)+
	lea.l	RMH_ROMTitle(a5),a1
	move.l	a1,(a0)+

	lea.l	.StringOne,a0
	lea.l	.DataTable,a1
	jsr	_PrintInfo

	lea.l	.Empty,a0
	jsr	_PrintInfo

	; find and print ROM Makeup

	clr.l	d0
	move.b	RMH_RomMakeup(a5),d0
	extb.l	d0

	lea.l	prg_ROMMakeupList,a0

.ROMMakeupSweep

	move.l	(a0)+,d1
	bmi	.ROMMakeupFound		;Out of entries, abort

	cmp.l	d0,d1
	beq	.ROMMakeupFound		;Found rommakeup, skip rest

	lea.l	4(a0),a0
	bra	.ROMMakeupSweep

.ROMMakeupFound

	lea.l	.DataTable,a1
	move.l	#.ROMMakeup,(a1)+
	move.l	(a0),(a1)+

	lea.l	.StringOne,a0
	lea.l	.DataTable,a1
	jsr	_PrintInfo

	lea.l	.Empty,a0
	jsr	_PrintInfo

	;ROM Type and ROM Size

	clr.l	d0
	move.b	RMH_ROMType(a5),d0

	lea.l	prg_ROMTypeList,a0

.ROMTypeSweep

	move.l	(a0)+,d1
	bmi	.ROMTypeFound		;Out of entries, abort

	cmp.l	d0,d1
	beq	.ROMTypeFound		;Found romtype, skip rest

	lea.l	4(a0),a0
	bra	.ROMTypeSweep

.ROMTypeFound

	lea.l	.DataTable,a1
	move.l	#.ROMType,(a1)+
	move.l	(a0),(a1)+

	clr.l	d0
	move.b	RMH_RomSize(a5),d0

	lea.l	prg_ROMSizeList,a0

.ROMSizeSweep

	move.l	(a0)+,d1
	bmi	.ROMSizeFound		;Out of entries, abort

	cmp.l	d0,d1
	beq	.ROMSizeFound		;Found romsize, skip rest

	lea.l	4(a0),a0
	bra	.ROMSizeSweep

.ROMSizeFound

	lea.l	.DataTable+8,a1
	move.l	#.ROMSize,(a1)+
	move.l	(a0),(a1)+

	lea.l	.StringTwo,a0
	lea.l	.DataTable,a1
	jsr	_PrintInfo

	lea.l	.Empty,a0
	jsr	_PrintInfo

	;SRAM Size and Country

	clr.l	d0
	move.b	RMH_SRAMSize(a5),d0

	lea.l	prg_SRAMSizeList,a0

.SRAMSizeSweep

	move.l	(a0)+,d1
	bmi	.SRAMSizeFound		;Out of entries, abort

	cmp.l	d0,d1
	beq	.SRAMSizeFound		;Found sramsize, skip rest

	lea.l	4(a0),a0
	bra	.SRAMSizeSweep

.SRAMSizeFound

	lea.l	.DataTable,a1
	move.l	#.SRAMSize,(a1)+
	move.l	(a0),(a1)+

	clr.l	d0
	move.b	RMH_CountryCode(a5),d0

	lea.l	prg_CountryList,a0

.CountrySweep

	move.l	(a0)+,d1
	bmi	.CountryFound		;Out of entries, abort

	cmp.l	d0,d1
	beq	.CountryFound		;Found country, skip rest

	lea.l	4(a0),a0
	bra	.CountrySweep

.CountryFound

	lea.l	.DataTable+8,a1
	move.l	#.Country,(a1)+
	move.l	(a0),(a1)+

	lea.l	.StringTwo,a0
	lea.l	.DataTable,a1
	jsr	_PrintInfo

	lea.l	.Empty,a0
	jsr	_PrintInfo

	movem.l	(sp)+,d0-a6
	rts

.Empty	dc.b	"",0

	even

.DataTable
	dc.l	0,0,0,0

.StringOne	dc.b	"%s %s",0
.StringTwo	dc.b	"%s %s, %s %s",0

.ROMTitle	dc.b	"Title:",0
.ROMMakeup	dc.b	"Setup:",0
.ROMType	dc.b	"Type:",0
.ROMSize	dc.b	"Size:",0
.SRAMSize	dc.b	"SRAM:",0
.Country	dc.b	"Country:",0

	cnop	0,4

_PrintInfo
*************************************************
* Scrolls the bitmap one 'chunk' up and prints	*
* new text.					*
*						*
* IN:	a0 - ptr to string.			*
*	a1 - ptr to value-list(for RawDoFmt())	*					*
*						*
*************************************************

	movem.l	d0-a6,-(sp)

	move.l	a0,.string
	move.l	a1,.data

	move.l	_GfxBase,a6
	move.l	SNESMenuWnd,a2
	move.l	wd_RPort(a2),a1
	move.l	#0,d0
	move.l	#8,d1
	move.b	wd_BorderLeft(a2),d2
	extb.l	d2
	move.b	wd_BorderTop(a2),d3
	extb.l	d3
	move.l	d2,d4
	move.l	d3,d5
	add.l	#4,d2
	add.l	#23,d3
	add.l	#322,d4
	add.l	#97,d5
	jsr	_LVOScrollRasterBF(a6)

	move.l	(4).w,a6
	move.l	.string,a0
	move.l	.data,a1
	lea.l	.writeout,a2
	lea.l	prg_StringBuffer,a3
	jsr	_LVORawDoFmt(a6)

	move.l	_IntuitionBase,a6
	move.l	SNESMenuWnd,a0
	move.l	wd_RPort(a0),a0
	lea.l	.intuistruct,a1
	move.l	#4+6,d0
	move.l	#37+8*8,d1
	jsr	_LVOPrintIText(a6)

	movem.l	(sp)+,d0-a6
	rts

.writeout
	move.b	d0,(a3)+
	rts

.string	dc.l	0
.data	dc.l	0

.intuistruct
	dc.b	1	;it_FrontPen
	dc.b	0	;it_BackPen

	dc.b	RP_JAM1	;it_DrawMode

	dc.b	0	;it_KludgeFill00

	dc.w	0	;it_LeftEdge
	dc.w	0	;it_TopEdge

	dc.l	topaz8	;it_ITextFont

	dc.l	prg_StringBuffer	;it_IText

	dc.l	0	;it_NextText

_EmulateSNES

	lea.l	prg_EmuRunning,a0
	jsr	_PrintInfo

	*** Emulation starts HERE ***

	lea.l	prg_CPUStructure,a0
	jsr	EMU_InitEmulation
	tst.l	d0
	bne	.no_emulation

	move.l	_IntuitionBase,a6
	move.l	SNESMenuWnd,a0
	lea.l	prg_BusyPointerTags,a1
	jsr	_LVOSetWindowPointerA(a6)

.EmuLoopOuter

	move.l	_IntuitionBase,a6
	move.l	ptr_EmulationScreen,a0
	jsr	_LVOScreenToFront(a6)

	move.l	ptr_EmulationWindow,a0
	jsr	_LVOActivateWindow(a6)

	move.l	_IntuitionBase,a6
	move.l	SNESMenuWnd,a0
	lea.l	prg_PointerTags,a1
	jsr	_LVOSetWindowPointerA(a6)

.Emulate
	lea.l	prg_CPUStructure,a0
	jsr	EMU_RunEmulation

	tst.l	prg_EmulError
	bne	.no_emulation

	tst.l	d0
	beq	.Emulate

.no_emulation

	tst.l	prg_EmulError
	beq	.no_emulerror

	* find exception string

	lea	prg_ExceptionTable,a2
	move.l	prg_EmulError,d2
.WalkExcList

	move.l	(a2)+,d0
	move.l	(a2)+,d1

	cmp.l	#EXC_UNKNOWN,d0
	beq	.ExcFound

	cmp.l	d0,d2
	beq	.ExcFound

	bra	.WalkExcList
.ExcFound

	lea.l	prg_CPUStructure,a2
	move.l	d1,CPU_Error(a2)

	move.l	CPU_Opcode(a2),d0
	lea.l	prg_MnemonicTable,a0
	and.l	#$ff,d0
	move.l	(a0,d0*4),d0
	move.l	d0,CPU_Mnemonic(a2)

	move.l	_IntuitionBase,a6
	move.l	Scr,a0
	jsr	_LVOScreenToFront(a6)

	lea.l	EmulAborted,a0
	lea.l	_AbortButton,a1
	jsr	ProgramRequest

	clr.l	prg_EmulError

	tst.l	d0
	bne	.no_debugging

	lea.l	prg_CPUStructure,a0
	jsr	EMU_Debugger

.no_debugging

	cmp.l	#2,d0
	beq	.EmuLoopOuter

.no_emulerror

	jsr	EMU_ScreenClose

	jsr	EMU_FinishEmulation

	*** Emulation stops HERE ***

	lea.l	prg_EmuHalted,a0
	jsr	_PrintInfo

	lea.l	prg_Empty,a0
	jsr	_PrintInfo

	rts

prg_GetScreenMode
* * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*							*
* Fetches the selected screenmode.			*
*							*
* IN:	d0 - current display-id.			*
*							*
* OUT:	d0 - Display ID or NULL.			*
*							*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * *

	movem.l	d1-a6,-(sp)

	move.l	d0,d7
	sub.l	a5,a5

	move.l	_ReqToolsBase,a6
	move.l	#RT_SCREENMODEREQ,d0
	sub.l	a0,a0
	jsr	_LVOrtAllocRequestA(a6)
	move.l	d0,a5
	beq	.Fail

	move.l	a5,a0
	lea.l	.taglist,a1
	move.l	d7,4(a1)
	jsr	_LVOrtChangeReqAttrA(a6)

	move.l	a5,a1
	lea.l	.title,a2
	sub.l	a3,a3
	jsr	_LVOrtScreenModeRequestA(a6)

	tst.l	d0
	beq	.Fail

	move.l	rtsc_DisplayID(a5),d7

.Fail

	tst.l	a5
	beq	.no_request

	move.l	a5,a1
	jsr	_LVOrtFreeRequest(a6)

.no_request

	move.l	d7,d0
	movem.l	(sp)+,d1-a6
	rts

.taglist	dc.l	RTSC_DisplayID,0,TAG_END
.title		dc.b	"Select screenmode...",0
	cnop	0,4

ProgramRequest
* * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*							*
* IN:	a0 - ptr to body text.				*
*	a1 - ptr to gadget text.			*
*	a2 - ptr to body arguments.			*
*							*
* OUT:	d0 - result.					*
*							*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * *

	movem.l	d1-a6,-(sp)

	move.l	_IntuitionBase,a6
	lea.l	.es_Struct,a3
	move.l	#20,es_StructSize(a3)
	move.l	#0,es_Flags(a3)
	move.l	#.req_Title,es_Title(a3)
	move.l	a0,es_TextFormat(a3)
	move.l	a1,es_GadgetFormat(a3)

	sub.l	a0,a0
	move.l	a3,a1
	move.l	a2,a3
	sub.l	a2,a2

	jsr	_LVOEasyRequestArgs(a6)

	movem.l	(sp)+,d1-a6
	rts

.req_Title	dc.b	"SNES Request",0
.es_Struct	ds.b	20

	section	data,data

prg_SNESLogoBitmap	dc.w	40
			dc.w	72
			dc.b	0
			dc.b	2
			dc.w	0
			dc.l	prgSNESLogoBitmap1
			dc.l	prgSNESLogoBitmap2
			dc.l	0
			dc.l	0
			dc.l	0
			dc.l	0
			dc.l	0
			dc.l	0

prg_SNESMenuTags	dc.l	GA_Disabled,0,TAG_END
prg_ROMInfoTags		dc.l	GTTX_Text,0,TAG_END
prg_CycleTags		dc.l	GTCY_Active,0,TAG_END
prg_CheckTags		dc.l	GTCB_Checked,0,TAG_END
prg_SlideTags		dc.l	GTSL_Level,0,TAG_END

prg_BusyPointerTags	dc.l	WA_BusyPointer,-1
			dc.l	WA_PointerDelay,-1
prg_PointerTags		dc.l	TAG_END

prg_CurrDirReq		dc.l	RTFI_Dir,prg_ConfigBuffer
			dc.l	TAG_END

	* strings

prg_EmuRunning		dc.b	"Emulation started...",0
prg_EmuHalted		dc.b	"Emulation halted.",0

prg_ConfigName		dc.b	"PROGDIR:AmiSNESE.config",0

prg_ROMInfoVersion	dc.b	"1.xx",0
prg_ROMInfoVBLVector	dc.b	"$xxxx",0
prg_ROMInfoResetVector	dc.b	"$xxxx",0
prg_ROMInfoInvalid	dc.b	"ERROR: No cartridge",0

prg_HexTable		dc.b	"0123456789ABCDEF"

_GfxName		dc.b	"graphics.library",0
_IntuitionName		dc.b	"intuition.library",0
_GadToolsName		dc.b	"gadtools.library",0
_ReqToolsName		dc.b	"reqtools.library",0
_DosName		dc.b	"dos.library",0

	cnop	0,4

prg_ExceptionTable
	dc.l	EXC_NOERROR,prg_ExcNoError
	dc.l	EXC_UNIMPL,prg_ExcUnimpl
	dc.l	EXC_ILLEGALMEM,prg_ExcIllegalMem
	dc.l	EXC_STOPCLOCK,prg_ExcStopClock

	dc.l	EXC_USERBREAK,prg_ExcUserBreak

	dc.l	EXC_UNKNOWN,prg_ExcUnknown

	* no error
prg_ExcNoError	dc.b	"No exception",0

	* emulation errors
prg_ExcUnimpl		dc.b	"Opcode not implemented",0
prg_ExcIllegalMem	dc.b	"Illegal memory-access",0
prg_ExcStopClock	dc.b	"Clock stopped",0

	* init errors
prg_ExcUnvalidHdr	dc.b	"Invalid ROM-header",0
prg_ExcOutOfMem		dc.b	"Out of memory",0
prg_ExcRomFail		dc.b	"ROM failure",0
prg_ExcHardInit		dc.b	"Hardware init failure",0
prg_ExcMemInit		dc.b	"Memory init failure",0
prg_ExcFadeFail		dc.b	"Fadetable init failure",0
prg_ExcResetFail	dc.b	"Reset failure",0
prg_ExcScreenFail	dc.b	"Screen opening failure",0

prg_ExcUserBreak	dc.b	"User break",0

prg_ExcUnknown		dc.b	"Unknown exception",0

EmulAborted
		dc.b	"Emulation interrupted!\n\n"
		dc.b	"Cause: %s. Opcode:%s($%lx)\n\nRegister dump:\n"
		dc.b	"X:$%x Y:$%x S:$%x A:$%x\n"
		dc.b	"PC:$%x D:$%x DB/PB:$%x P:$%x",0

_AbortButton	dc.b	"Ok|Continue Emulation|Enter Debugger",0
_OkButton	dc.b	"Ok",0

prg_Empty	dc.b	0

	section	bss,bss

_GfxBase		ds.l	1
_IntuitionBase		ds.l	1
_GadToolsBase		ds.l	1
_DosBase		ds.l	1
_ReqToolsBase		ds.l	1

prg_Error		ds.l	1
ptr_Message		ds.l	1
ptr_StartupMessage	ds.l	1
ptr_ThisTask		ds.l	1
prg_Terminate		ds.l	1
ptr_FileRequester	ds.l	1

prg_ForceROM		ds.l	1

prg_ROMHeader		ds.b	RMH_SIZEOF
prg_FileNameBuffer	ds.b	2048
prg_StringBuffer	ds.b	1024

prg_ConfigBuffer	ds.b	CFG_SIZEOF

	section	data,data_c

	IFEQ	AF

prgSNESLogoBitmap1	incbin	"!SNES:data/SNESLogo_plane1.raw"
prgSNESLogoBitmap2	incbin	"!SNES:data/SNESLogo_plane2.raw"

	ELSE

prgSNESLogoBitmap1	incbin	"!SNES:data/SNESLogoAF_plane1.raw"
prgSNESLogoBitmap2	incbin	"!SNES:data/SNESLogoAF_plane2.raw"

	ENDIF
