	include	'exec/types.i'
	include	'exec/memory.i'
	include	'exec/interrupts.i'
	include	'exec/io.i'
	include	'exec/libraries.i'
	include 'exec/execbase.i'
	include	'exec/exec_lib.i'
	include	'graphics/gfxbase.i'
	include	'graphics/displayinfo.i'
	include	'intuition/intuition.i'
	include 'intuition/intuition_lib.i'
	include	'devices/audio.i'
	include	'devices/scsidisk.i'
	include	'hardware/custom.i'
	include	'hardware/intbits.i'
	include	'hardware/dmabits.i'
	include	'hardware/adkbits.i'
	include	'hardware/cia.i'
	include	'graphics/graphics_lib.i'
	include	'dos/dos.i'
	include	'dos/dos_lib.i'
	include	'audio_driver.i'
	include	'resource.i'

UNKNOWN		EQU	-1
APPLECD300	EQU	0
APPLECD150	EQU	1
TOSHIBA3401	EQU	2

CDDA_BLOCKSIZE	EQU	2352
TOC_SIZE	EQU	804

	STRUCTURE dq_DiskQueue,0
		APTR	dq_prev
		UWORD	dq_itemNo
		LABEL	dq_SIZEOF

	STRUCTURE s_TrackNode,0
		APTR 	tn_prev
		APTR	tn_next
		UWORD	tn_trackNo
		ULONG	tn_startBlock
		ULONG	tn_endBlock
		LABEL	tn_SIZEOF


	STRUCTURE lin_LineNode,0
		APTR	lin_next
		APTR	lin_string
		LABEL	lin_SIZEOF

	section audio_code,code

;**********************************************************************

Start:

	bsr	StartResource
	move.l	a0,d0
	bsr	ListCommand
	tst.l	d0
	beq	sta_1
	move.l	d0,line_Str
	
	bsr	ReadPrefs	
	bsr	OpenSCSI
	bsr	OpenAudio
	bsr	ReadTracks	
	
	move.l	line_Str(pc),d0
sta_3	tst.l	end_Prog
	beq	sta_E
	move.l	d0,a5
	move.l	lin_string(a5),a0
	bsr	atoi
	tst.l	a0
	beq	sta_1
	move.l	d0,d7

	move.l	d7,d0
	bsr	GetTrack
	tst.l	d0
	beq	sta_2
	bsr	PlayCDROM
	
	move.l	lin_next(a5),d0
	bne	sta_3
	
sta_E	bsr	FreeAll
	rts

sta_1	lea	UsageMessage(pc),a0
	bsr	NotifyError
	bra	sta_E
	
sta_2	lea	sta_errMsg(pc),a0
	bsr	NotifyError
	bra	sta_E

line_Str	dc.l	0
end_Prog	dc.l	1

BufBlocks	dc.l	2
UsageMessage	dc.b	'Usage: PlayTrack <track numbers e.g. 1 2 3>',0
sta_errMsg	dc.b	'Specified track not found.',0

;**********************************************************************

	cnop	0,4

	;d0	=	track structure

PlayCDROM:

	movem.l	d0-d7/a0-a6,-(sp)
	move.l	d0,a0
	move.l	tn_startBlock(a0),currentBlock
	move.l	tn_endBlock(a0),endBlock
	bsr	ActivateNewResource
	move.l	d0,playRes
	move.l	4.w,a6
	suba.l	a1,a1
	jsr	_LVOFindTask(a6)
	move.l	d0,thisTask
	move.l	d0,a1
	moveq	#27,d0
	jsr	_LVOSetTaskPri(a6)
	moveq	#2,d3
	lea	ReadCmd(pc),a2
	lea	AudioSignals(pc),a3
	lea	diskQueue(pc),a4
PCD_1	moveq	#12,d0
	move.l	#MEMF_PUBLIC|MEMF_CLEAR,d1
	moveq	#E_PLACE|E_FATALERROR,d2
	bsr	GetMem
	move.l	d0,(a2,d3.w*4)
	moveq	#-1,d0
	moveq	#E_PLACE|E_FATALERROR,d1
	bsr	NewSignal
	move.b	d0,(a3,d3.w)
	moveq	#dq_SIZEOF,d0
	move.l	#MEMF_PUBLIC|MEMF_CLEAR,d1
	moveq	#E_PLACE|E_FATALERROR,d2
	bsr	GetMem
	move.l	d0,(a4,d3.w*4)
	dbra	d3,PCD_1
PCD_2a	moveq	#0,d7
	lea	ReadCmd(pc),a5
	lea	ASyncIO(pc),a4
PCD_2	move.l	currentBlock(pc),d0
	cmp.l	endBlock(pc),d0
	bhi	PCD_E
	move.l	(a4,d7.w*4),a0
	move.l	(a5,d7.w*4),a1
	move.b	scsi_readCmd(pc),(a1)
	move.b	#0,1(a1)
	move.l	d0,2(a1)
	move.l	BufBlocks(pc),d1
	move.l	d1,6(a1)
	move.b	#0,10(a1)
	move.b	#0,11(a1)
	add.l	d1,d0
	move.l	d0,currentBlock
	moveq	#12,d0
	lea	audioBuffers(pc),a2
	move.l	(a2,d7.w*4),a2
	mulu.l	#CDDA_BLOCKSIZE,d1
	moveq	#SCSIF_READ,d2
	moveq	#0,d3
	lea	readCmd_msg(pc),a3
	bsr	DoSCSI
	tst.l	d0
	beq	PLP_Err
	lea	diskQueue(pc),a1
	move.l	(a1,d7.w*4),a1
	move.l	topDiskQ(pc),d0
	beq	PCD_3
	move.l	d0,a0
	move.l	a1,dq_prev(a0)
	bra	PCD_4
PCD_3	move.l	a1,bottomDiskQ
PCD_4	move.l	a1,topDiskQ
	clr.l	dq_prev(a1)
	move.w	d7,dq_itemNo(a1)
	addq.w	#1,d7
	cmpi.w	#3,d7
	bcs	PCD_2
	bsr	PlayLoop
PCD_E	
	bsr	FlushStream
	move.l	_DOSBase(pc),a6
	move.l	BufBlocks(pc),d1
	mulu.l	#10,d1
	jsr	_LVODelay(a6)

	move.l	playRes(pc),d0
	bsr	RemoveResource
	movem.l	(sp)+,d0-d7/a0-a6
	rts

;**********************************************************************

PlayLoop:

	moveq	#0,d7		;d7	=	signal
	bra	PLP_8
	
PLP_1	move.l	currentBlock(pc),d0
	cmp.l	endBlock(pc),d0
	bhi	PLP_E
	move.l	d7,d6
	moveq	#0,d2
	moveq	#0,d0
	lea	AudioSignals(pc),a0
	moveq	#2,d3
PLP_2	move.b	(a0)+,d2
	moveq	#1,d1
	lsl.l	d2,d1
	or.l	d1,d0
	dbra	d3,PLP_2
	
	ori.l	#SIGBREAKF_CTRL_D|SIGBREAKF_CTRL_C,d0
	move.l	4.w,a6
	
	jsr	_LVOWait(a6)

	move.l	d0,d7
	or.l	d6,d7
	move.l	d7,d6
	andi.l	#SIGBREAKF_CTRL_D,d6
	bne	PLP_E
	
	move.l	d7,d6
	andi.l	#SIGBREAKF_CTRL_C,d6
	beq	PLP_4ac
	clr.l	end_Prog
	bra	PLP_E
	
PLP_4ac	moveq	#0,d5
PLP_4	lea	AudioSignals(pc),a0
	moveq	#1,d0
	moveq	#0,d1
	move.b	(a0,d5.w),d1
	lsl.l	d1,d0
	move.l	d7,d6
	and.l	d0,d6
	beq	PLP_5
	eor.l	d0,d7
	lea	ASyncIO(pc),a0
	move.l	(a0,d5.w*4),a0
	lea	ReadCmd(pc),a1
	move.l	(a1,d5.w*4),a1
	move.b	scsi_readCmd(pc),(a1)
	move.b	#0,1(a1)
	move.l	currentBlock(pc),d0
	move.l	BufBlocks(pc),d1
	move.l	d0,2(a1)
	move.l	d1,6(a1)
	add.l	d1,d0
	move.l	d0,currentBlock
	moveq	#12,d0
	mulu.l	#CDDA_BLOCKSIZE,d1
	lea	audioBuffers(pc),a2
	move.l	(a2,d5.w*4),a2
	moveq	#SCSIF_READ,d2
	moveq	#0,d3
	lea	readCmd_msg(pc),a3
	bsr	DoSCSI
	tst.l	d0
	beq	PLP_Err
	
	lea	diskQueue(pc),a1
	move.l	(a1,d5.w*4),a1
	move.l	topDiskQ(pc),d0
	beq	PLP_6
	move.l	d0,a0
	move.l	a1,dq_prev(a0)
	bra	PLP_7
PLP_6	move.l	a1,bottomDiskQ
PLP_7	move.l	a1,topDiskQ
	clr.l	dq_prev(a1)
	move.w	d5,dq_itemNo(a1)
PLP_5	addq.w	#1,d5
	cmpi.w	#3,d5
	bcs	PLP_4
		
PLP_8	move.l	bottomDiskQ(pc),d0
	beq	PLP_9
	move.l	d0,a0
	move.w	dq_itemNo(a0),d5
	
	move.l	dq_prev(a0),d0
	move.l	d0,bottomDiskQ
	bne	PLP_10
	clr.l	topDiskQ
	
PLP_10	bsr	_SD_Lock
	move.l	qualityNumber(pc),d4
	lea	audioBuffers(pc),a0
	move.l	(a0,d5.w*4),a0
	move.l	a0,a1
	add.l	#2,a1
	move.l	BufBlocks(pc),d0
	mulu.l	#CDDA_BLOCKSIZE,d0
	moveq	#4,d1
	mulu.w	d4,d1
	divu.l	d1,d0
	move.l	d4,d1
	lsl.l	#1,d1
	subq.w	#1,d1
	move.l	#44100,d2
	divu.l	d4,d2
	moveq	#0,d6
	lea	AudioSignals(pc),a3
	move.b	(a3,d5.w),d6
	move.l	d6,a2
	bsr	_ProvideStream
	bsr	_SD_Unlock
	bra	PLP_8
	
PLP_9	bra	PLP_1
PLP_E	rts

PLP_Err

	lea	readErr(pc),a0
	bsr	FatalError
	rts

AudioFunc:

	movem.l	d0-d7/a0-a6,-(sp)
	move.l	a5,d0
	move.l	d0,signalVal
	moveq	#1,d1
	lsl.l	d0,d1
	move.l	d1,d0
	move.l	thisTask(pc),a1
	move.l	4.w,a6
	jsr	_LVOSignal(a6)
	movem.l	(sp)+,d0-d7/a0-a6
	rts
	
qualityNumber	dc.l	2
signalVal	dc.l	0

currentBlock	dc.l	0
endBlock	dc.l	0
	
playRes		dc.l	0

topDiskQ	dc.l	0
bottomDiskQ	dc.l	0
diskQueue	dc.l	0,0,0

ReadCmd		dc.l	0,0,0
AudioSignals	dc.b	0,0,0,0
thisTask	dc.l	0

scsi_readCmd	dc.b	$d8

readCmd_msg	dc.b	'Reading data from CDDA.',0
readErr		dc.b	'Error reading CDDA data.',0

;**********************************************************************

	cnop	0,4

	;a0	=	string
	;return d0	=	number
	;	a0	=	0=FALSE

atoi:
	move.l	d1,-(sp)
	moveq	#0,d0
	moveq	#0,d1
atoi_2	move.b	(a0)+,d1
	beq	atoi_1
	mulu.l	#10,d0
	cmpi.w	#$30,d1
	blt	atoi_E
	cmpi.w	#$39,d1
	bgt	atoi_E
	andi.w	#$000f,d1
	add.l	d1,d0
	bra	atoi_2
atoi_1	move.l	(sp)+,d1
	rts
	
atoi_E	move.l	(sp)+,d1
	suba.l	a0,a0
	rts

;**********************************************************************

ReadPrefs:

	movem.l	d0/a0-a1/a5,-(sp)
	lea	rp_PrefsFilename(pc),a0
	move.l	a0,d0
	bsr	ParseCommandFile
	move.l	d0,a5
	lea	rp_device(pc),a0
	move.l	a5,a1
	bsr	FindStringValue
	tst.l	d0
	beq	RP_1
	move.l	d0,scsi_namePtr
RP_1	lea	rp_unit(pc),a0
	move.l	a5,a1
	bsr	FindStringValue
	tst.l	d0
	beq	RP_2
	move.l	d0,a0
	bsr	atoi
	tst.l	a0
	beq	RP_2
	move.l	d0,scsi_unit
RP_2	lea	rp_quality(pc),a0
	move.l	a5,a1
	bsr	FindStringValue
	tst.l	d0
	beq	RP_3
	move.l	d0,a0
	bsr	atoi
	tst.l	a0
	beq	RP_3
	move.l	d0,qualityNumber
RP_3	movem.l	(sp)+,d0/a0-a1/a5
	rts

rp_device	dc.b	'DEVICE',0
rp_unit		dc.b	'UNIT',0
rp_quality	dc.b	'QUALITY',0
rp_PrefsFilename	dc.b	'S:playtrack.prefs',0

;**********************************************************************

	cnop	0,4

	;a0	=	parameter string
	;a1	=	string list

FindStringValue:

	movem.l	d1-d2/d7/a2-a3,-(sp)
	moveq	#0,d7
FSV_1	tst.l	a1
	beq	FSV_2
	move.l	lin_string(a1),a2
	move.l	a0,a3
	moveq	#0,d0
FSV_3	move.b	(a2)+,d1
	beq	FSV_4
	move.b	(a3)+,d2
	beq	FSV_4
	cmpi.b	#'=',d1
	beq	FSV_4
	sub.b	d2,d1
	addx.b	d1,d0
	bra	FSV_3
FSV_4	tst.l	d0
	beq	FSV_5
	move.l	lin_next(a1),a1
	bra	FSV_1
FSV_5	move.l	a2,d7
FSV_2	move.l	d7,d0
	movem.l	(sp)+,d1-d2/d7/a2-a3
	rts


;**********************************************************************

	;d0	=	Prefs file name

ParseCommandFile:

	movem.l	d1-d5/a0-a6,-(sp)
	move.l	d0,d1
	bsr	ActivateNewResource
	move.l	d0,prefsRes
	move.l	#MODE_OLDFILE,d2
	moveq	#E_PLACE|E_FATALERROR,d3
	bsr	OpenFile
	move.l	d0,d5
	move.l	#228+32,d0
	move.l	#MEMF_PUBLIC,d1
	moveq	#E_PLACE|E_FATALERROR,d2
	bsr	GetMem
	move.l	d0,a5
	move.l	_DOSBase(pc),a6
	move.l	d5,d1
	move.l	d0,d2
	jsr	_LVOExamineFH(a6)
	tst.w	d0
	bne	PCF_1
	lea	pcf_Err1(pc),a0
	bsr	FatalError
PCF_1	move.l	fib_Size(a5),d0
	move.l	d0,d4
	addq.l	#1,d0
	move.l	#MEMF_PUBLIC,d1
	moveq	#E_PLACE|E_FATALERROR,d2
	bsr	GetMem
	move.l	d0,a4
	move.l	d5,d1
	move.l	d0,d2
	move.l	d4,d3
	jsr	_LVORead(a6)
	cmp.l	d0,d4
	beq	PCF_2
	lea	pcf_Err2(pc),a0
	bsr	FatalError
PCF_2	suba.l	a5,a5
	moveq	#1,d3
	subq.l	#1,d4
PCF_3	cmpi.b	#' ',(a4)
	beq	PCF_4
	cmpi.b	#$0a,(a4)
	beq	PCF_4
	tst.b	d3
	beq	PCF_5
	moveq	#lin_SIZEOF,d0
	move.l	#MEMF_PUBLIC|MEMF_CLEAR,d1
	moveq	#E_PLACE|E_FATALERROR,d2
	bsr	GetMem
	tst.l	a5
	beq	PCF_6
	move.l	d0,lin_next(a3)
	bra	PCF_7
PCF_6	move.l	d0,a5
PCF_7	move.l	d0,a3
	move.l	a4,lin_string(a3)
	moveq	#0,d3
	bra	PCF_5
PCF_4	moveq	#1,d3
	clr.b	(a4)
PCF_5	lea	1(a4),a4
	dbra	d4,PCF_3
	clr.b	(a4)
	move.l	a5,d0
	movem.l	(sp)+,d1-d5/a0-a6
	rts

prefsRes	dc.l	0

pcf_Err1	dc.b	'Could not file information from file.',0
pcf_Err2	dc.b	'Unexpected end of file',0

;**********************************************************************

	cnop	0,4

	;d0	=	command line
	
ListCommand:

	movem.l	d1-d3/a3-a5,-(sp)
	move.l	d0,a5
	bsr	ActivateNewResource
	move.l	d0,listRes
	suba.l	a4,a4
	moveq	#1,d3
LC_6	cmpi.b	#' ',(a5)
	beq	LC_1
	cmpi.b	#$0a,(a5)
	beq	LC_3
	tst.b	d3
	beq	LC_2
	moveq	#lin_SIZEOF,d0
	move.l	#MEMF_PUBLIC|MEMF_CLEAR,d1
	moveq	#E_PLACE|E_FATALERROR,d2
	bsr	GetMem
	tst.l	a4
	beq	LC_4
	move.l	d0,lin_next(a3)
	bra	LC_5
LC_4	move.l	d0,a4
LC_5	move.l	d0,a3
	move.l	a5,lin_string(a3)
	moveq	#0,d3
	bra	LC_2
LC_1	moveq	#1,d3
	clr.b	(a5)
LC_2	lea	1(a5),a5
	bra	LC_6
LC_3	clr.b	(a5)
	move.l	a4,d0
	movem.l	(sp)+,d1-d3/a3-a5
	rts
	
listRes		dc.l	0

;**********************************************************************

ReadTracks:
	
	movem.l	d0-d2/d5-d7/a0-a6,-(sp)
	bsr	ActivateNewResource
	move.l	d0,trackRes
	move.l	#804,d0
	move.l	#MEMF_PUBLIC|MEMF_CLEAR,d1
	moveq	#E_FATALERROR,d2
	bsr	GetMem
	move.l	d0,a5
	move.l	d0,TOCData
	move.l	SyncIO(pc),a0
	lea	TOCRead(pc),a1
	move.l	a5,a2
	lea	TOCmsg(pc),a3
	moveq	#10,d0
	move.l	#804,d1
	moveq	#SCSIF_READ,d2
	moveq	#0,d3
	bsr	DoSCSI
	tst.l	d0
	beq	RT_3
	moveq	#0,d7
	moveq	#4,d6
	moveq	#8,d5
	move.l	a5,a4
	add.l	d6,a4
	move.b	3(a5),d7
	move.b	2(a5),d6
RT_1	subq.w	#1,d7
	subq.w	#1,d6
	beq	RT_2
	add.l	d5,a4
	bra	RT_1
RT_2	tst.w	d7
	blt	RT_3
	suba.l	a3,a3
RT_2a	moveq	#tn_SIZEOF,d0
	move.l	#MEMF_PUBLIC|MEMF_CLEAR,d1
	moveq	#E_PLACE|E_FATALERROR,d2
	bsr 	GetMem
	move.l	d0,a2
	move.l	a3,tn_prev(a2)
	tst.l	a3
	beq	RT_2b
	move.l	a2,tn_next(a3)
	bra	RT_2c
RT_2b	move.l	a2,trackList
RT_2c	move.w	d6,tn_trackNo(a2)
	move.l	4(a4),tn_startBlock(a2)
	move.l	d0,-(sp)
	move.l	12(a4),d0
	subi.l	#15,d0
	move.l	d0,tn_endBlock(a2)
	move.l	(sp)+,d0
	move.l	a2,a3
	add.l	d5,a4
	addq.w	#1,d6
	dbra	d7,RT_2a
RT_3	move.l	4.w,a6
	move.l	a5,a1
	move.l	#804,d0
	jsr	_LVOFreeMem(a6)
	movem.l	(sp)+,d0-d2/d5-d7/a0-a6
	rts

TOCData		dc.l	0

TOCRead		dc.b	$43,0
		dc.l	0
		dc.b	0,TOC_SIZE>>8,(TOC_SIZE&$ff),0

trackList	dc.l	0
trackRes	dc.l	0

TOCmsg		dc.b	'Reading Table of Contents',0

;**********************************************************************

	cnop	0,4

	;d0	=	trackNo
	;return	=	trackEntry
	
GetTrack:

	move.l	a0,-(sp)
	subq.w	#1,d0
	move.l	trackList(pc),a0
GT_2	tst.l	a0
	beq	GT_1
	cmp.w	tn_trackNo(a0),d0
	beq	GT_1
	move.l	tn_next(a0),a0
	bra	GT_2
GT_1	move.l	a0,d0
	move.l	(sp)+,a0
	rts

;**********************************************************************

OpenAudio:

	movem.l	d0-d2/d6-d7/a5,-(sp)
	bsr	InitDriver
	tst.w	d0
	beq	OA_E
	move.l	#CDDA_BLOCKSIZE>>2,d0
	moveq	#4,d1
	bsr	SetBuffers
	tst.w	d0
	beq	OA_E
	move.l	#$49313662,d0
	bsr	StreamFormat
	tst.l	d0
	beq	OA_E
	move.l	BufBlocks(pc),d7
	mulu.l	#CDDA_BLOCKSIZE,d7
	moveq	#0,d6
	lea	audioBuffers(pc),a5
OA_1	move.l	d7,d0
	move.l	#MEMF_CLEAR,d1
	moveq	#E_PLACE|E_FATALERROR,d2
	bsr	GetVec
	move.l	d0,(a5,d6.w*4)
	addq.w	#1,d6
	cmpi.w	#3,d6
	bne	OA_1
	movem.l	(sp)+,d0-d2/d6-d7/a5
	rts
	
OA_E	lea	audioErr(pc),a0
	bsr	FatalError
	rts

audioBuffers	dc.l	0,0,0

audioErr	dc.b	'Could not open audio device',0

;**********************************************************************

OpenSCSI:

	movem.l	d0-d7/a0-a6,-(sp)
	bsr	ActivateNewResource
	move.l	d0,scsiRes
	moveq	#E_PLACE|E_FATALERROR,d0
	bsr	R_NewMsgPort
	move.l	d0,SyncPort
	move.l	d0,a0
	moveq	#48,d0
	moveq	#E_PLACE|E_FATALERROR,d1
	bsr	R_NewIORequest
	move.l	d0,SyncIO
	move.l	d0,a2
	moveq	#30,d0
	move.l	#MEMF_PUBLIC|MEMF_CLEAR,d1
	moveq	#E_PLACE|E_FATALERROR,d2
	bsr	GetMem
	move.l	d0,SyncCmd
	move.l	d0,a3
	moveq	#38,d0
	move.w	d0,26(a3)
	move.l	#MEMF_PUBLIC|MEMF_CLEAR,d1
	moveq	#E_PLACE|E_FATALERROR,d2
	bsr	GetMem
	move.l	d0,SyncSense
	move.l	d0,22(a3)
	move.l	a3,40(a2)
	move.l	scsi_namePtr(pc),a0
	move.l	a2,a1
	lea	SyncUse(pc),a2
	move.l	scsi_unit(pc),d0
	moveq	#0,d1
	moveq	#E_PLACE|E_FATALERROR,d2
	bsr	OpenDeviceRes
	moveq	#0,d7
OSC_1	moveq	#E_PLACE|E_FATALERROR,d0
	bsr	R_NewMsgPort
	lea	ASyncPort(pc),a0
	move.l	d0,(a0,d7.w*4)
	move.l	d0,a0
	moveq	#48,d0
	moveq	#E_PLACE|E_FATALERROR,d1
	bsr	R_NewIORequest
	lea	ASyncIO(pc),a0
	move.l	d0,(a0,d7.w*4)
	move.l	d0,a2
	moveq	#30,d0
	move.l	#MEMF_PUBLIC|MEMF_CLEAR,d1
	moveq	#E_PLACE|E_FATALERROR,d2
	bsr	GetMem
	lea	ASyncCmd(pc),a0
	move.l	d0,(a0,d7.w*4)
	move.l	d0,a3
	moveq	#38,d0
	move.w	d0,26(a3)
	move.l	#MEMF_PUBLIC|MEMF_CLEAR,d1
	moveq	#E_PLACE|E_FATALERROR,d2
	bsr	GetMem
	lea	ASyncSense(pc),a0
	move.l	d0,(a0,d7.w*4)
	move.l	d0,22(a3)
	move.l	a3,40(a2)
	move.l	scsi_namePtr(pc),a0
	move.l	a2,a1
	lea	ASyncUse(pc),a2
	add.l	d7,a2
	move.l	scsi_unit(pc),d0
	moveq	#0,d1
	moveq	#E_PLACE|E_FATALERROR,d2
	bsr	OpenDeviceRes
	addq.w	#1,d7
	cmpi.w	#3,d7
	bne	OSC_1
	bsr	FindDriveBrand
	cmpi.w	#TOSHIBA3401,d0
	bne	OS_E
	move.b	#$a8,scsi_readCmd
	move.l	SyncIO(pc),a0
	lea	ModeSense(pc),a1
	moveq	#6,d0
	lea	OldModePage,a2
	moveq	#12,d1
	moveq	#SCSIF_READ,d2
	moveq	#0,d3
	lea	OS_modeS(pc),a3
	bsr	DoSCSI
	move.l	SyncIO(pc),a0
	lea	ModeSelect(pc),a1
	moveq	#6,d0
	lea	NewModePage(pc),a2
	moveq	#12,d1
	moveq	#SCSIF_WRITE,d2
	moveq	#0,d3
	lea	OS_modeSel(pc),a3
	bsr	DoSCSI
	lea	SCSIChangeMode(pc),a0
	move.l	a0,d2
	moveq	#R_FUNCTION,d0
	moveq	#rl_SIZEOF,d1
	bsr	Res_PlaceList
OS_E	movem.l	(sp)+,d0-d7/a0-a6
	rts
	
	
SCSIChangeMode:
	
	movem.l	d0-d3/a0-a3,-(sp)
	move.l	SyncIO(pc),a0
	lea	ModeSelect(pc),a1
	moveq	#6,d0
	lea	OldModePage,a2
	moveq	#12,d1
	moveq	#SCSIF_WRITE,d2
	moveq	#0,d3
	lea	OS_oldS(pc),a3
	bsr	DoSCSI
	movem.l	(sp)+,d0-d3/a0-a3
	rts
	

scsiRes		dc.l	0

SyncPort	dc.l	0
SyncIO		dc.l	0
SyncCmd		dc.l	0
SyncSense	dc.l	0

ASyncPort	dc.l	0,0,0
ASyncIO		dc.l	0,0,0
ASyncCmd	dc.l	0,0,0
ASyncSense	dc.l	0,0,0

SyncUse		dc.b	0
ASyncUse	dc.b	0,0,0

ModeSense	dc.b	$1a,0,1,0,12,0
ModeSelect	dc.b	$15,$10,0,0,12,0
NewModePage	dc.b	0,0,0,8,$82,0,0,0
		dc.l	CDDA_BLOCKSIZE
OS_modeS	dc.b	'reading mode page',0
OS_modeSel	dc.b	'selecting CDDA data format',0
OS_oldS		dc.b	'reseting data format',0

scsi_namePtr	dc.l	scsi_name
scsi_name	dc.b	'gvpscsi.device',0
scsi_unit	dc.l	3
	
;**********************************************************************

	cnop	0,4
	
	;return		=	d0

FindDriveBrand:

	movem.l	d1-d2/d6-d7/a0-a3/a5-a6,-(sp)
	moveq	#UNKNOWN,d6
	move.l	#1000,d7
	move.l	d7,d0
	move.l	#MEMF_PUBLIC|MEMF_CLEAR,d1
	moveq	#E_FATALERROR,d2
	bsr	GetMem
	move.l	d0,a5
	move.l	SyncIO(pc),a0
	lea	fdb_inqCmd(pc),a1
	moveq	#6,d0
	move.l	a5,a2
	move.l	d7,d1
	moveq	#SCSIF_AUTOSENSE|SCSIF_READ,d2
	moveq	#0,d3
	lea	fdb_inqCmdName(pc),a3
	bsr	DoSCSI
	tst.w	d0
	beq	FDB_1
	adda.l	#8,a5
	move.l	a5,a0
	lea	fdb_apple300ID(pc),a1
	moveq	#APPLECD300,d6
	bsr	FDB_MCmp
	tst.l	d0
	beq	FDB_2
	move.l	a5,a0
	lea	fdb_apple150ID(pc),a1
	moveq	#APPLECD150,d6
	bsr	FDB_MCmp
	tst.l	d0
	beq	FDB_2
	move.l	a5,a0
	lea	fdb_toshibaID(pc),a1
	moveq	#TOSHIBA3401,d6
	bsr	FDB_MCmp
	tst.l	d0
	beq	FDB_2
	moveq	#UNKNOWN,d6
FDB_2	suba.l	#8,a5
FDB_1	move.l	a5,a1
	move.l	d7,d0
	move.l	4.w,a6
	jsr	_LVOFreeMem(a6)
	move.l	d6,d0
	movem.l	(sp)+,d1-d2/d6-d7/a0-a3/a5-a6
	rts


FDB_MCmp:

	moveq	#0,d0
	moveq	#0,d1
FDB_M1	move.b	(a0)+,d1
	beq	FDB_ME
	move.b	(a1)+,d2
	beq	FDB_ME
	subx.b	d2,d1
	add.l	d1,d0
	bra	FDB_M1
FDB_ME	rts
	
	cnop	0,4

fdb_inqCmd	dc.b	$12,0,0,0,252,0

fdb_inqCmdName	dc.b	'Reading drive type',0
fdb_apple300ID	dc.b	'SONY    CD-ROM CDU-8003',0
fdb_apple150ID	dc.b	'SONY    CD-ROM CDU-8002',0
fdb_toshibaID	dc.b	'TOSHIBA',0


;**********************************************************************

	cnop	0,4


	;return TRUE/FALSE	=	d0

InitDriver:

	movem.l	d1-d7/a0-a6,-(sp)
	
	bsr	ActivateNewResource
	move.l	d0,audioRes
	
	moveq	#E_PLACE|E_RETRYERROR,d0
	bsr	R_NewMsgPort
	tst.l	d0
	bne	ID_1
	bsr	E_CloseDriver
	bra	ID_R
	
ID_1	move.l	d0,AudioReply
	move.l	d0,a0
	moveq	#ioa_SIZEOF,d0
	moveq	#E_PLACE|E_RETRYERROR,d1
	bsr	R_NewIORequest
	tst.l	d0
	bne	ID_2
	bsr	E_CloseDriver
	bra	ID_R
	
ID_2	move.l	d0,AudioRequest
	move.l	d0,a1
	move.b	#127,$9(a1)
	move.b	#$40,$1e(a1)
	lea	ChannelMap(pc),a0
	move.l	a0,$22(a1)
	move.l	#1,$26(a1)
	lea	audio_name(pc),a0	
	lea	audDeviceUse(pc),a2
	moveq	#0,d0
	moveq	#0,d1
	moveq	#E_PLACE|E_RETRYERROR,d2
	bsr	OpenDeviceRes
	tst.l	d0
	beq	ID_3
	bsr	E_CloseDriver
	bra	ID_R
	
ID_3	move.l	#(65536*2),d0
	moveq	#0,d1
	moveq	#E_PLACE|E_RETRYERROR,d2
	bsr	GetVec
	tst.l	d0
	bne	ID_4
	bsr	E_CloseDriver
	bra	ID_R
	
ID_4	move.l	d0,ConversionTable
	move.l	d0,a2
	move.l	#256,d0
	moveq	#0,d1
	moveq	#E_PLACE|E_RETRYERROR,d2
	bsr	GetVec
	tst.l	d0
	bne	ID_5
	bsr	E_CloseDriver
	bra	ID_R
	
ID_5	move.l	d0,AdditiveTable
	move.l	d0,a3
	lea	audioCalbName(pc),a0
	move.l	a0,d1
	move.l	#MODE_OLDFILE,d2
	move.l	_DOSBase(pc),a6
	jsr	_LVOOpen(a6)
	move.l	d0,d7
	beq	ID_6
	move.l	d0,d1
	move.l	a3,d2
	move.l	#256,d3
	jsr	_LVORead(a6)
	cmpi.w	#256,d0
	beq	ID_7
	
ID_6	move.w	#254,d0
	move.l	a3,a0
ID_6a	move.b	#$55,(a0)+
	dbra	d0,ID_6a
	move.b	#$7f,(a0)+

ID_7	tst.l	d7
	beq	ID_8
	move.l	d7,d1
	jsr	_LVOClose(a6)
	
ID_8	move.l	a2,a0
	move.l	a3,a1
	bsr	CreateTable
	move.l	#'M16b',CurrentFormat
	
	move.l	#$dff000,a5
	move.w	#DMAF_AUDIO,$96(a5)
	move.w	#$00ff,$9e(a5)
	moveq	#INTB_AUD0,d0
	lea	NOPVector(pc),a4
	move.l	a4,a1
	move.l	4.w,a6
	jsr	_LVOSetIntVector(a6)
	move.l	d0,OldAudVector0
	moveq	#INTB_AUD1,d0
	move.l	a4,a1
	jsr	_LVOSetIntVector(a6)
	move.l	d0,OldAudVector1
	moveq	#INTB_AUD2,d0
	move.l	a4,a1
	jsr	_LVOSetIntVector(a6)
	move.l	d0,OldAudVector2
	lea	AudioVector(pc),a1
	moveq	#INTB_AUD3,d0
	jsr	_LVOSetIntVector(a6)
	move.l	d0,OldAudVector3
	move.w	#$0780,$9a(a5)
	move.w	#$0780,$9c(a5)
	move.w	#$8400,$9a(a5)
	
	moveq	#R_FUNCTION,d0
	moveq	#rl_SIZEOF,d1
	lea	DeInitDriver(pc),a0
	move.l	a0,d2
	bsr	Res_PlaceList
		
	move.l	#1024,d0
	moveq	#16,d1
	bsr	SetBuffers
	tst.l	d0
	beq	ID_R
	
	moveq	#1,d7
	
ID_R	movem.l	(sp)+,d1-d7/a0-a6
	rts

audioRes	dc.l	0


audio_name	dc.b	'audio.device',0
audioCalbName	dc.b	'ENV:CyberSound/SoundDrivers/14Bit_Calibration',0
	
	cnop	0,4

ErrorAdr	dc.l	0
ErrorStack	dc.l	0
	
AudioReply	dc.l	0
AudioRequest	dc.l	0

ConversionTable	dc.l	0
AdditiveTable	dc.l	0
CurrentFormat	dc.l	'M16b'
OldAudVector0	dc.l	0
OldAudVector1	dc.l	0
OldAudVector2	dc.l	0
OldAudVector3	dc.l	0
NestLevel	dc.w	0
DriverFlags	dc.w	FLGF_NEEDIRQ

ChannelMap	dc.b	15

AudioVector	dc.l	0,0
		dc.b	NT_INTERRUPT
		dc.b	0
		dc.l	int_Name
		dc.l	0
		dc.l	AudioInterrupt
		
NOPVector	dc.l	0,0
		dc.b	NT_INTERRUPT
		dc.b	0
		dc.l	int_Name
		dc.l	0
		dc.l	NOPInterrupt

audDeviceUse	dc.b	0

int_Name	dc.b	'14 bit driver',0
ID_err1		dc.b	'Could not open audio device',0

;**********************************************************************

	cnop	0,4

@DeInitDriver
_DeInitDriver
DeInitDriver:

	movem.l	d0-d1/a0-a1/a6,-(sp)
	bsr	FreeBuffers
	move.l	4.w,a6
	move.w	#$0780,$dff09a
	move.w	#$0780,$dff09c
	tst.l	OldAudVector0
	beq	DID_1
	move.l	#INTB_AUD0,d0
	move.l	OldAudVector0(pc),a1
	jsr	_LVOSetIntVector(a6)
DID_1	tst.l	OldAudVector1
	beq	DID_2
	move.l	#INTB_AUD1,d0
	move.l	OldAudVector1(pc),a1
	jsr	_LVOSetIntVector(a6)
DID_2	tst.l	OldAudVector2
	beq	DID_3
	move.l	#INTB_AUD2,d0
	move.l	OldAudVector2(pc),a1
	jsr	_LVOSetIntVector(a6)
DID_3	tst.l	OldAudVector3
	beq	DID_4
	move.l	#INTB_AUD3,d0
	move.l	OldAudVector3(pc),a1
	jsr	_LVOSetIntVector(a6)
DID_4	movem.l	(sp)+,d0-d1/a0-a1/a6
	rts


;**********************************************************************

	;audiosize	=	d0
	;queuesize	=	d1
	
	;success	=	d0

_SetBuffers
@SetBuffers
SetBuffers

	movem.l	d2/d5-d7/a0-a1/a6,-(sp)
	bsr	FreeBuffers
	move.l	d0,BUFFER_SIZE
	move.l	d0,d7
	move.l	d7,RIGHT_MSB
	lsl.l	#1,d7
	move.l	d7,RIGHT_LSB
	add.l	d0,d7
	move.l	d7,LEFT_LSB
	move.l	d1,QUEUE_SIZE
	moveq	#0,d7
	lsl.l	#2,d0
	mulu.l	#sia_SIZEOF,d1
	move.l	d0,d5
	move.l	d1,d6
	move.l	#MEMF_CHIP,d1
	moveq	#E_RETRYERROR,d2
	bsr	GetVec
	move.l	d0,DMABuffer1
	bne	SB_1
	bsr	E_CloseDriver
	bra	SB_R
SB_1	move.l	d5,d0
	move.l	#MEMF_CHIP,d1
	moveq	#E_RETRYERROR,d2
	bsr	GetVec
	move.l	d0,DMABuffer2
	bne	SB_2
	bsr	E_CloseDriver
	bra	SB_R
SB_2	move.l	d6,d0
	move.l	#MEMF_CLEAR,d1
	moveq	#E_RETRYERROR,d2
	bsr	GetVec
	move.l	d0,QueueBuffer
	bne	SB_3
	bsr	E_CloseDriver
	bra	SB_R
SB_3	bsr	FlushStream
	moveq	#1,d0
SB_R	movem.l	(sp)+,d2/d5-d7/a0-a1/a6
	rts	
	
DMABuffer1	dc.l	0
DMABuffer2	dc.l	0
QueueBuffer	dc.l	0
BUFFER_SIZE	dc.l	0
QUEUE_SIZE	dc.l	0
LEFT_MSB	dc.l	0
RIGHT_MSB	dc.l	0
RIGHT_LSB	dc.l	0
LEFT_LSB	dc.l	0

;**********************************************************************

FreeBuffers

	movem.l	d0-d1/a0-a1/a6,-(sp)
	move.l	4.w,a6
	bsr	_FlushStream
	move.l	DMABuffer1(pc),a1
	tst.l	a1
	beq	FB_1
	jsr	_LVOFreeVec(a6)
	clr.l	DMABuffer1
FB_1	move.l	DMABuffer2(pc),a1
	tst.l	a1
	beq	FB_2
	jsr	_LVOFreeVec(a6)
	clr.l	DMABuffer2
FB_2	move.l	QueueBuffer(pc),a1
	tst.l	a1
	beq	FB_3
	jsr	_LVOFreeVec(a6)
	clr.l	QueueBuffer
	clr.l	BUFFER_SIZE
	clr.l	QUEUE_SIZE
FB_3	movem.l	(sp)+,d0-d1/a0-a1/a6
	rts

;**********************************************************************

E_CloseDriver:

	lea	audio_eMsg(pc),a0
	bsr	NotifyError
	move.l	audioRes(pc),d0
	bsr	RemoveResource
	moveq	#0,d0
	rts

audio_eMsg	dc.b	'Error in audio device:',$0a,'shutting audio down.',0

;**********************************************************************

	cnop	0,4

	;d0	=	format
	;result	=	d0

_StreamFormat
@StreamFormat	
StreamFormat
	
	movem.l	d1/d7,-(sp)
	bsr	FlushStream
	moveq	#0,d7
	move.l	CurrentFormat(pc),d1
	cmpi.l	#'M16b',d0
	bne	SF_1
	cmpi.l	#'I16b',d1
	bne	SF_1
	bra	SF_2
SF_1	cmpi.l	#'I16b',d0
	bne	SF_3
	cmpi.l	#'M16b',d1
	bne	SF_3
SF_2	bsr	SwapEndian
	move.l	d0,CurrentFormat
	moveq	#1,d7
SF_3	move.l	d7,d0
SF_E	movem.l	(sp)+,d1/d7
	rts


;**********************************************************************

_AskFrequency
@AskFrequency
AskFrequency

	movem.l	d1/a6,-(sp)
	bsr	AskPeriod
	move.l	4.w,a6
	move.l	$238(a6),d1
	mulu.l	#5,d1
	divu.l	d0,d1
	move.l	d1,d0
AF_E	movem.l	(sp)+,d1/a6
	rts


;**********************************************************************

	;d0	=	frequency
	;peroid	=	d0
	
AskPeriod

	movem.l	d1-d2/a0,-(sp)
	move.l	_GfxBase,a0
	move.w	$ce(a0),d1
	andi.w	#$0004,d1
	beq	AP_1
	move.l	#3546895,d1
	bra	AP_2
AP_1	move.l	#3579545,d1	
AP_2	divu.l	d0,d1
	move.l	d1,d0
	movem.l	(sp)+,d1-d2/a0
	rts

;**********************************************************************

	;a0	=	left
	;a1	=	right
	;d0	=	samples
	;d1	=	interleave
	;d2	=	frequency
	;a2	=	callback
	;d6	=	offset
	
	;result	=	d0

_ProvideStream
@ProvideStream

	movem.l	d3-d5/d7/a3,-(sp)
	moveq	#0,d7
	move.l	QueueBuffer(pc),a3
	tst.l	a3
	beq	PS_1
	tst.l	DMABuffer1
	beq	PS_1
	tst.l	DMABuffer2
	beq	PS_1
	move.l	ProvidePos(pc),d3
	move.l	d3,d5
	addq.w	#1,d3
	divul.l	QUEUE_SIZE(pc),d4:d3
	cmp.l	PlayPos(pc),d4
	beq	PS_1
	bsr	_SD_Lock
	mulu.l	#sia_SIZEOF,d5
	add.l	d5,a3
	move.l	a0,sia_left(a3)
	move.l	a1,sia_right(a3)
	move.l	d0,sia_samples(a3)
	move.w	d1,sia_interleave(a3)
	move.l	d2,d0
	bsr	AskPeriod
	move.l	d0,sia_period(a3)
	move.l	a2,sia_callback(a3)
	move.l	d4,ProvidePos
	move.w	DriverFlags(pc),d0
	moveq	#FLGF_NEEDIRQ,d1
	and.w	d0,d1
	beq	PS_2
	not.w	d1
	and.w	d1,d0
	move.w	d0,DriverFlags
	move.w	#$8400,$dff09c
PS_2	bsr	_SD_Unlock
	moveq	#1,d7	
PS_1	move.l	d7,d0
PS_E	movem.l	(sp)+,d3-d5/d7/a3
	rts
	
ProvidePos	dc.l	0
PlayPos		dc.l	0

;**********************************************************************

_FlushStream
@FlushStream
FlushStream
	
	tst.l	QueueBuffer
	beq	FS_E
	movem.l	d0,-(sp)
	moveq	#FLGF_FLUSH,d0
	or.w	d0,DriverFlags
	move.w	#$8400,$dff09c
	move.w	#1,$dff0a6
	move.w	#1,$dff0b6
	move.w	#1,$dff0c6
	move.w	#1,$dff0d6
	movem.l	(sp)+,d0
FS_E	rts

;**********************************************************************

@PauseStream
_PauseStream
	
	move.w	d0,-(sp)
	move.w	#FLGF_PAUSE,d0
	or.w	d0,DriverFlags
	move.w	d0,(sp)+
	rts

;**********************************************************************

@ResumeStream
_ResumeStream

	movem.w	d0-d1,-(sp)
	move.w	#~(FLGF_PAUSE),d0
	move.w	DriverFlags(pc),d1
	and.w	d0,d1
	move.w	d1,d0
	andi.w	#FLGF_NEEDIRQ,d0
	beq	RS_1
	move.w	#~(FLGF_NEEDIRQ),d0
	and.w	d0,d1
	move.w	#$8400,$dff09c
RS_1	move.w	d1,DriverFlags
	movem.w	(sp)+,d0-d1
	rts

;**********************************************************************

_StopDMA
@StopDMA
StopDMA

	move.w	d0,-(sp)
	move.w	DriverFlags(pc),d0
	btst	#FLGB_PLAYING,d0
	beq	SDMA_1
	andi.w	#~(FLGF_PLAYING),d0
	ori.w	#FLGF_NEEDIRQ,d0
	move.w	#$000f,$dff096
	move.w	#0,$dff0a8
	move.w	#0,$dff0b8
	move.w	#0,$dff0c8
	move.w	#0,$dff0d8
SDMA_1	move.w	(sp)+,d0
	rts


;**********************************************************************

@SD_Lock
_SD_Lock

	tst.w	NestLevel
	bne	SDL_1
	move.w	#$0400,$dff09a
SDL_1	addi.w	#1,NestLevel
	rts


;**********************************************************************

@SD_Unlock
_SD_Unlock

	tst.w	NestLevel
	beq	SDU_1
	subi.w	#1,NestLevel
	tst.w	NestLevel
	bne	SDU_1
	move.w	#$8400,$dff09a
SDU_1	rts

;**********************************************************************

	cnop	0,4

NOPInterrupt

	move.w	d1,-(sp)
	andi.w	#$0380,d1
	move.w	d1,$dff09c
	move.w	(sp)+,d1
	rts
	
;**********************************************************************

	cnop	0,4

	;d1	=	ActiveInt

_AudioInterrupt
AudioInterrupt
	
	movem.l	d0-d7/a0-a6,-(sp)
	move.l	#$dff000,a5
	andi.w	#$0400,d1
	move.w	d1,($9c.w,a5)
	move.b	$bfe001,d0
	ori.b	#$02,d0
	move.b	d0,$bfe001
	move.w	DriverFlags(pc),d7
	btst	#FLGB_PLAYING,d7
	beq.b	AI_1
	move.w	LastPeriod(pc),d1
	move.w	d1,($a6.w,a5)
	move.w	d1,($b6.w,a5)
	move.w	d1,($c6.w,a5)
	move.w	d1,($d6.w,a5)
	bra.b	AI_2
AI_1	ori.w	#FLGF_NEEDIRQ,d7
AI_2	move.l	PlayPos(pc),d4
	move.l	ProvidePos(pc),d5
	move.l	QueueBuffer(pc),a4
AI_3	cmp.l	d4,d5
	beq	AI_4
	move.l	a4,a0
	move.l	d4,d1
	mulu.l	#sia_SIZEOF,d1
	adda.l	d1,a0
	cmpi.l	#$ffffffff,sia_offset(a0)
	beq	AI_3a
	btst	#FLGB_FLUSH,d7
	beq	AI_4
AI_3a	addq.l	#1,d4
	divul.l	QUEUE_SIZE(pc),d1:d4
	move.l	d1,d4
	cmp.l	d4,d5
	beq	AI_3ba
	btst	#FLGB_FLUSH,d7
	beq	AI_3b
AI_3ba	bsr	StopDMA
	andi.w	#~(FLGF_FLUSH|FLGF_PLAYING),d7
	ori.w	#FLGF_NEEDIRQ,d7
AI_3b	movem.l	d0-d1/a0-a1/a5,-(sp)

	move.l	sia_callback(a0),a5
	bsr	AudioFunc
	
	move.l	a0,a5
	moveq	#sia_SIZEOF-1,d0
AB_3c	move.b	#0,(a5)+
	dbra	d0,AB_3c
	movem.l	(sp)+,d0-d1/a0-a1/a5
	bra	AI_3
AI_4	btst	#FLGB_FLUSH,d7
	beq	AI_5
	move.w	#1,CurrentBuffer
	clr.l	PlayPos
	moveq	#0,d5
	andi.w	#~(FLGF_FLUSH|FLGF_PLAYING),d7
	ori.w	#FLGF_NEEDIRQ,d7
	bra	AI_6
AI_5	move.l	d4,PlayPos
AI_5b	cmp.l	d4,d5
	beq	AI_7
AI_5a	move.l	a4,a0
	move.l	d4,d1
	mulu.l	#sia_SIZEOF,d1
	adda.l	d1,a0
	move.l	sia_offset(a0),d1
	cmp.l	sia_samples(a0),d1
	bcs	AI_7
	move.l	#$ffffffff,sia_offset(a0)
	addq.l	#1,d4
	divul.l	QUEUE_SIZE(pc),d1:d4
	move.l	d1,d4
	cmp.l	d4,d5
	bne	AI_5a
	ori.w	#FLGF_NEEDIRQ,d7
AI_7	btst	#FLGB_PAUSE,d7
	beq	AI_8
	bsr	StopDMA
	andi.w	#~(FLGF_PLAYING),d7
	ori.w	#FLGF_NEEDIRQ,d7
	bra	AI_6
AI_8	move.w	CurrentBuffer(pc),d1
	cmpi.w	#1,d1
	bne.b	AI_8a
	move.l	DMABuffer1(pc),a6
	bra.b	AI_8b
AI_8a	move.l	DMABuffer2(pc),a6
AI_8b	moveq	#0,d2
	moveq	#0,d6
	move.w	d7,-(sp)
	move.l	ConversionTable(pc),a3
AI_10	cmp.l	BUFFER_SIZE(pc),d2
	bcc	AI_9
	cmp.l	d4,d5
	beq	AI_9
	move.l	QueueBuffer(pc),a4
	move.l	d4,d1
	mulu.l	#sia_SIZEOF,d1
	adda.l	d1,a4
	move.l	sia_samples(a4),d3
	sub.l	sia_offset(a4),d3
	ble	AI_10a
	move.l	BUFFER_SIZE(pc),d0
	sub.l	d2,d0
	cmp.l	d0,d3
	ble	AI_10b
	move.l	d0,d3
AI_10b	tst.w	d6
	beq.b	AI_10c
	cmp.l	sia_period(a4),d6
	bne	AI_9
	bra.b	AI_10d
AI_10c	move.l	sia_period(a4),d6
AI_10d	move.l	sia_offset(a4),d7
	moveq	#0,d0
	move.w	sia_interleave(a4),d0
	addq.w	#1,d0
	mulu.l	d0,d7
	move.l	sia_left(a4),a0
	lsl.l	#1,d7
	adda.l	d7,a0
	move.l	a6,a1
	adda.l	d2,a1
	move.l	a1,a2
	adda.l	LEFT_LSB(pc),a2
	move.l	d3,d0
	move.w	sia_interleave(a4),d1
	move.l	ConversionTable(pc),a3
	bsr	ConvertStream
	move.l	sia_right(a4),a0
	adda.l	d7,a0
	move.l	a6,a1
	adda.l	d2,a1
	move.l	a1,a2
	adda.l	RIGHT_MSB(pc),a1
	adda.l	RIGHT_LSB(pc),a2
	move.l	d3,d0
	move.w	sia_interleave(a4),d1
	move.l	ConversionTable(pc),a3
	bsr	ConvertStream
	add.l	d3,sia_offset(a4)
	add.l	d3,d2
AI_10a	addq.l	#1,d4
	divul.l	QUEUE_SIZE(pc),d1:d4
	move.l	d1,d4
	bra	AI_10
AI_9	move.w	(sp)+,d7
	tst.l	d2
	beq	AI_6
	move.w	d6,LastPeriod
	move.l	a6,($a0.w,a5)
	adda.l	BUFFER_SIZE(pc),a6
	move.l	a6,($b0.w,a5)
	adda.l	BUFFER_SIZE(pc),a6
	move.l	a6,($c0.w,a5)
	adda.l	BUFFER_SIZE(pc),a6
	move.l	a6,($d0.w,a5)
	move.w	_VolumeR(pc),($a8.w,a5)
	move.w	_VolumeL(pc),($b8.w,a5)
	move.w	#1,($c8.w,a5)
	move.w	#1,($d8.w,a5)
	lsr.l	#1,d2
	move.w	d2,($a4.w,a5)
	move.w	d2,($b4.w,a5)
	move.w	d2,($c4.w,a5)
	move.w	d2,($d4.w,a5)
	btst	#FLGB_PLAYING,d7
	bne	AI_9a
	ori.w	#FLGF_PLAYING,d7
	move.w	d6,($a6.w,a5)
	move.w	d6,($b6.w,a5)
	move.w	d6,($c6.w,a5)
	move.w	d6,($d6.w,a5)
	move.w	#$800f,($96.w,a5)
AI_9a	addi.w	#1,CurrentBuffer
	cmpi.w	#3,CurrentBuffer
	bne	AI_6
	move.w	#1,CurrentBuffer
AI_6	move.w	d7,DriverFlags
	move.l	d5,ProvidePos
	movem.l	(sp)+,d0-d7/a0-a6
	rts

LastPeriod	dc.w	1
CurrentBuffer	dc.w	0

_audioMP	dc.l	0
_replyMP	dc.l	0

_VolumeL	dc.w	64
_VolumeR	dc.w	64


;**********************************************************************


CreateTable:

	movem.l	a2/d2-d6,-(sp)
	lea	128(a1),a2
	move.l	a2,a1
	moveq	#128-1,d0
	moveq	#0,d5
CT_1	move.b	(a1)+,d1
	ext.w	d1
	ext.l	d1
	add.l	d1,d5
	dbra	d0,CT_1
	move.l	#32768,d6
	move.l	a2,a1
	move.w	#32768-1,d0
	moveq	#0,d1
	moveq	#0,d2
	moveq	#0,d3
CT_2	move.b	(a1)+,d4
	ext.w	d4
	add.w	d4,d3
CT_3	tst.w	d3
	bgt.s	CT_5
CT_4	addq.w	#1,d1
	sub.w	d4,d2
	bra.s	CT_2
CT_5	move.b	d1,(a0)+
	move.b	d2,(a0)+
	sub.l	d5,d6
	bpl.s	CT_6
	add.l	#32768,d6
	addq.w	#1,d2
	subq.w	#1,d3
CT_6	dbra	d0,CT_3
	move.l	a2,a1
	moveq	#128-1,d0
	moveq	#0,d5
CT_7	move.b	-(a1),d1
	ext.w	d1
	ext.l	d1
	add.l	d1,d5
	dbra	d0,CT_7
	move.l	#32768,d6
	add.l	#2*32768,a0
	move.l	a2,a1
	move.w	#32768-1,d0
	moveq	#-1,d1
	moveq	#-1,d2
	moveq	#0,d3
CT_8	move.b	-(a1),d4
	ext.w	d4
	add.w	d4,d3
	add.w	d4,d2
CT_9	tst.w	d3
	bgt.s	CT_11
CT_10	subq.w	#1,d1
	bra.s	CT_8
CT_11	move.b	d2,-(a0)
	move.b	d1,-(a0)
	sub.l	d5,d6
	bpl.s	CT_12
	add.l	#32768,d6
	subq.w	#1,d2
	subq.w	#1,d3
CT_12	dbra	d0,CT_9
	movem.l	(sp)+,a2/d2-d6
	rts

;**********************************************************************
	
SwapEndian:
	
	movem.l	d0-d3/a0,-(sp)
	move.w	#65535,d0
	move.l	ConversionTable(pc),a0
	moveq	#0,d1
SE_1	move.l	d1,d2
	rol.w	#8,d2
	cmp.l	d1,d2
	bhs.s	SE_2
	move.w	(a0,d1.l*2),d3
	move.w	(a0,d2.l*2),(a0,d1.l*2)
	move.w	d3,(a0,d2.l*2)
SE_2	addq.l	#1,d1
	dbra	d0,SE_1
	movem.l	(sp)+,d0-d3/a0
	rts

;**********************************************************************
	
ConvertStream

	movem.l	d2-d4/a2-a3,-(sp)
	addq.w	#1,d1
	add.w	d1,d1
	moveq	#0,d2
	move.w	d0,-(sp)
	lsr.l	#2,d0
	bra.s	CS_3
CS_1	swap	d0
CS_2	move.w	(a0),d2
	add.w	d1,a0
	move.w	(a3,d2.l*2),d3
	move.b	d3,d4
	rol.w	#8,d4
	move.w	(a0),d2
	add.w	d1,a0
	move.b	(a3,d2.l*2),d3
	swap	d3
	move.b	1(a3,d2.l*2),d4
	swap	d4
	move.w	(a0),d2
	add.w	d1,a0
	move.w	(a3,d2.l*2),d3
	move.b	d3,d4
	rol.w	#8,d4
	move.w	(a0),d2
	add.w	d1,a0
	move.b	(a3,d2.l*2),d3
	move.l	d3,(a1)+
	move.b	1(a3,d2.l*2),d4
	move.l	d4,(a2)+
CS_3	dbra	d0,CS_2
	swap	d0
	dbra	d0,CS_1
	move.w	(sp)+,d0
	andi.w	#$3,d0
	bra.s	CS_5
CS_4	move.w	(a0),d2
	add.w	d1,a0
	move.b	(a3,d2.l*2),(a1)+
	move.b	1(a3,d2.l*2),(a2)+
CS_5	dbra	d0,CS_4
	movem.l	(sp)+,d2-d4/a2-a3
	rts


;**********************************************************************

	XDEF	_StartResource
	XDEF	@StartResource
	
_StartResource
@StartResource
StartResource:

	movem.l	d0-d1/a0-a1,-(sp)
	bsr	ActivateNewResource
	lea	intuition_name(pc),a1
	moveq	#0,d0
	moveq	#E_PLACE|E_FATALERROR,d1
	bsr	R_OpenLibrary
	move.l	d0,_IntuitionBase
	lea	dos_name(pc),a1
	moveq	#0,d0
	moveq	#E_PLACE|E_FATALERROR,d1
	bsr	R_OpenLibrary
	move.l	d0,_DOSBase
	lea	graphics_name(pc),a1
	moveq	#0,d0
	moveq	#E_PLACE|E_FATALERROR,d1
	bsr	R_OpenLibrary
	move.l	d0,_GfxBase
	movem.l	(sp)+,d0-d1/a0-a1
	rts
	
graphics_name	dc.b	'graphics.library',0
intuition_name	dc.b	'intuition.library',0
dos_name	dc.b	'dos.library',0

;**********************************************************************

	;Global Variables

	cnop	0,4

_IntuitionBase	dc.l	0
_DOSBase	dc.l	0
_GfxBase	dc.l	0
originalStack	dc.l	0
	
mainList	dc.l	0
resList		dc.l	0
resNext		dc.l	0


;**********************************************************************

	cnop	0,4
	
	XDEF	_OpenFile
	XDEF	@OpenFile
	
_OpenFile
@OpenFile
OpenFile:

	;d1	=	fileName
	;d2	=	accessMode
	;d3	=	flags
	
	movem.l	d4-d5/a0-a1/a6,-(sp)
	move.l	d1,d4
	move.l	d2,d5
	move.l	_DOSBase(pc),a6
OF_3	jsr	_LVOOpen(a6)
	move.l	d0,d2
	bne	OF_1
	lea	OF_err1(pc),a0
	lea	textArea,a1
	bsr	StrCpy
	move.l	d4,a0
	bsr	StrCpy
	lea	OF_err2(pc),a0
	bsr	StrCpy
	lea	textArea,a0
	bsr	ProduceError
	tst.w	d0
	beq	OF_2
	move.l	d4,d1
	move.l	d5,d2
	bra	OF_3
OF_1	andi.b	#E_PLACE,d3
	beq	OF_2
	moveq	#R_FILE,d0
	moveq	#rl_SIZEOF,d1
	bsr	Res_PlaceList
OF_2	move.l	d2,d0
	movem.l	(sp)+,d4-d5/a0-a1/a6
	rts


OF_err1		dc.b	'Could not open file "',0
OF_err2		dc.b	'".',0

;**********************************************************************

	cnop	0,4

	;d0=memSize
	;d1=memType
	;d2.w=memFlags
	
	;return = d0
	
	;scrap registers d0,d1

	XDEF	_GetMem
	XDEF	@GetMem
	
_GetMem
@GetMem
GetMem:

	movem.l	d2/d5-d6/a0-a1/a6,-(sp)
	move.l	d0,d5
	move.l	d1,d6
	move.l	4.w,a6
GM_1	jsr	_LVOAllocMem(a6)
	exg	d0,d2
	tst.l	d2
	bne.b	GM_2
	move.w	d0,d2
	lea	GM_errorMsg(pc),a0
	bsr	ProduceError
	tst.w	d0
	beq	GM_3
	move.l	d5,d0
	move.l	d6,d1
	bra.b	GM_1
GM_2	andi.b	#E_PLACE,d0
	beq.b	GM_3
	moveq	#R_MEMORY,d0
	moveq	#rmr_SIZEOF,d1
	bsr	Res_PlaceList
	move.l	d5,rm_memSize(a0)
GM_3	move.l	d2,d0
	movem.l	(sp)+,d2/d5-d6/a0-a1/a6
	rts
	
GM_errorMsg	dc.b	'Could not allocate enough memory.',0

;**********************************************************************

	;a1	=	libName
	;d0	=	version No.
	;d1.w	=	Flags
	;return	=	d0
	
	XDEF	_R_OpenLibrary
	XDEF	@R_OpenLibrary
	
_R_OpenLibrary
@R_OpenLibrary
R_OpenLibrary:

	movem.l	d2-d5/a0/a6,-(sp)
	move.l	d0,d3
	move.w	d1,d5
	move.l	a1,d4
	move.l	4.w,a6
R_OP1a	jsr	_LVOOpenLibrary(a6)
	move.l	d0,d2
	bne	R_OP1
	lea	R_OP_msg1(pc),a0
	lea	textArea,a1
	bsr	StrCpy
	move.l	d4,a0
	bsr	StrCpy
	lea	R_OP_msg2(pc),a0
	bsr	StrCpy
	move.l	d3,d0
	bsr	itoa
	lea	R_OP_msg3(pc),a0
	bsr	StrCpy
	clr.b	(a1)
	lea	textArea,a0
	move.w	d5,d0
	bsr	ProduceError
	tst.w	d0
	beq	R_OP2
	move.l	d3,d0
	move.l	d4,a1
	bra	R_OP1a
R_OP1	andi.w	#E_PLACE,d5
	beq	R_OP2
	moveq	#R_LIBRARY,d0
	moveq	#rl_SIZEOF,d1
	bsr	Res_PlaceList
R_OP2	move.l	d2,d0
	movem.l	(sp)+,a0/d2-d5/a6
	rts

R_OP_msg1	dc.b	'Could not open library "',0
R_OP_msg2	dc.b	'" V',0
R_OP_msg3	dc.b	'.',0

;**********************************************************************
	
	cnop	0,4
	
	;d0	=	msgFlags
	;return =	d0
	
	XDEF	_R_NewMsgPort
	XDEF	@R_NewMsgPort
		
_R_NewMsgPort
@R_NewMsgPort
R_NewMsgPort:

	movem.l	d1-d3/a0-a1/a6,-(sp)
	move.w	d0,d3
	move.l	4.w,a6
R_NMP3	jsr	_LVOCreateMsgPort(a6)
	move.l	d0,d2
	bne	R_NMP1
	lea	R_NMP_errorMsg(pc),a0
	move.l	d3,d0
	bsr	ProduceError
	tst.l	d0
	beq	R_NMP2
	bra	R_NMP3
R_NMP1	andi.b	#E_PLACE,d3
	beq	R_NMP2
	moveq	#R_MSGPORT,d0
	moveq	#rl_SIZEOF,d1
	bsr	Res_PlaceList
R_NMP2	move.l	d2,d0
	movem.l	(sp)+,d1-d3/a0-a1/a6
	rts

R_NMP_errorMsg	dc.b	'Could not allocate message port.',0

;**********************************************************************

	cnop	0,4
	
	;a0	=	MsgPort
	;d0	=	size
	;d1	=	ioFlags
	;return	=	d0
	
	XDEF	_R_NewIORequest
	XDEF	@R_NewIORequest
	
_R_NewIORequest
@R_NewIORequest
R_NewIORequest:

	movem.l	d2-d4/a1-a2/a6,-(sp)
	move.l	a0,a2
	move.l	d0,d3
	move.w	d1,d4
	move.l	4.w,a6
R_NIO1	jsr	_LVOCreateIORequest(a6)
	move.l	d0,d2
	bne	R_NIO2
	lea	R_NIO_errorMsg(pc),a0
	move.l	d4,d0
	bsr	ProduceError
	tst.l	d0
	beq	R_NIO3
	move.l	a2,a0
	move.l	d3,d0
	bra	R_NIO1
R_NIO2	andi.b	#E_PLACE,d4
	beq	R_NIO3
	moveq	#R_IOREQUEST,d0
	moveq	#rl_SIZEOF,d1
	bsr	Res_PlaceList
R_NIO3	move.l	d2,d0
	movem.l	(sp)+,d2-d4/a1-a2/a6
	rts
	
R_NIO_errorMsg	dc.b	'Could not create IO port',0
	

;**********************************************************************
	
	;a0	=	device name
	;d0	=	device unit
	;a1	=	ioRequest
	;a2	=	devF
	;d1	=	device flags
	;d2	=	flags

	cnop	0,4

	XDEF	_OpenDeviceRes
	XDEF	@OpenDeviceRes
	
_OpenDeviceRes
@OpenDeviceRes
OpenDeviceRes:

	movem.l	d3-d5/a3-a4/a6,-(sp)
	move.l	a0,a4
	move.l	a1,a3
	move.l	d0,d3
	move.l	d1,d4
	move.l	4.w,a6
ODR_1	jsr	_LVOOpenDevice(a6)
	move.l	d0,d5
	beq	ODR_2
	lea	textArea,a1
	lea	ODR_msg1(pc),a0
	bsr	StrCpy
	move.l	a4,a0
	bsr	StrCpy
	lea	ODR_msg2(pc),a0
	bsr	StrCpy
	move.l	d3,d0
	bsr	itoa
	lea	ODR_msg3(pc),a0
	bsr	StrCpy
	clr.b	(a1)
	lea	textArea,a0
	move.l	d2,d0
	bsr	ProduceError
	tst.l	d0
	beq	ODR_3
	move.l	a4,a0
	move.l	a3,a1
	move.l	d3,d0
	move.l	d4,d1
	bra	ODR_1
ODR_2	andi.b	#E_PLACE,d2
	beq	ODR_3
	moveq	#R_DEVICE,d0
	moveq	#rd_SIZEOF,d1
	move.l	a3,d2
	bsr	Res_PlaceList
	move.l	a2,rd_checkFlag(a0)
ODR_3	move.l	d5,d0
	movem.l	(sp)+,d3-d5/a3-a4/a6
	rts

ODR_msg1	dc.b	'Could not open "',0
ODR_msg2	dc.b	'" unit-',0
ODR_msg3	dc.b	'.',0
	
;**********************************************************************

	cnop	0,4
	
	;d0	=	signalNum
	;d1	=	flags
	;return	=	d0
	
	XDEF	_NewSignal
	XDEF	@NewSignal
	
_NewSignal
@NewSignal
NewSignal:

	movem.l	d2-d4/a0-a1/a6,-(sp)
	move.w	d0,d3
	move.w	d1,d4
	move.l	4.w,a6
NS_1	jsr	_LVOAllocSignal(a6)
	move.l	d0,d2
	tst.b	d0
	bpl	NS_2
	lea	NS_errorMsg(pc),a0
	move.l	d4,d0
	bsr	ProduceError
	tst.w	d0
	beq	NS_3
	move.w	d3,d0
	bra	NS_1
NS_2	andi.b	#E_PLACE,d4
	beq	NS_3
	moveq	#R_SIGNAL,d0
	moveq	#rl_SIZEOF,d1
	bsr	Res_PlaceList
NS_3	move.l	d2,d0
	movem.l	(sp)+,d2-d4/a0-a1/a6
	rts
	
NS_errorMsg	dc.b	'Could not allocate signal bit',0

;**********************************************************************

	cnop	0,4

	;d0	=	byteSize
	;d1	=	attributes
	;d2	=	flag
	;return	=	d0
	
	XDEF	_GetVec
	XDEF	@GetVec
	
_GetVec
@GetVec
GetVec:

	movem.l	d3-d5/a0-a1/a6,-(sp)
	move.l	d0,d3
	move.l	d1,d4
	move.w	d2,d5
	move.l	4.w,a6
GV_1	jsr	_LVOAllocVec(a6)
	move.l	d0,d2
	bne	GV_2
	lea	GV_errorMsg(pc),a0
	move.l	d5,d0
	bsr	ProduceError
	tst.w	d0
	beq	GV_3
	move.l	d3,d0
	move.l	d4,d1
	bra	GV_1
GV_2	andi.w	#E_PLACE,d5
	beq	GV_3
	moveq	#R_VEC,d0
	moveq	#rl_SIZEOF,d1
	bsr	Res_PlaceList
GV_3	move.l	d2,d0
	movem.l	(sp)+,d3-d5/a0-a1/a6
	rts

GV_errorMsg	dc.b	'Not enough memory aviable.',0
	
;**********************************************************************


	cnop	0,4
		
	;a0	=	source
	;a1	=	destination
	
StrCpy:
	move.b	(a0)+,d0
	beq	ST_E
	move.b	d0,(a1)+
	bra	StrCpy
ST_E	rts

;**********************************************************************

	;d0.l	=	number
	;a1	=	string buffer
	
itoa:	movem.l	d1-d2/a0,-(sp)
	lea	textAreaB,a0
	tst.l	d0
	bpl	itoa_1a
	move.b	#'-',(a1)+
itoa_1a	moveq	#0,d2
itoa_1	divul.l	#10,d1:d0
	addi.b	#$30,d1
	move.b	d1,(a0)+
	addq.w	#1,d2
	tst.l	d0
	bne	itoa_1
	subq.w	#1,d2
itoa_2	move.b	-(a0),(a1)+
	dbra	d2,itoa_2
	movem.l	(sp)+,d1-d2/a0
	rts

;**********************************************************************

	;d0	=	type
	;d1	=	sizeof
	;d2.l	=	item
	;return	=	a0

	;scrap d0,d1

	XDEF	_Res_PlaceList
	XDEF	@Res_PlaceList
	
_Res_PlaceList
@Res_PlaceList	
Res_PlaceList:

	movem.l	d3-d4/a1,-(sp)
	move.w	d0,d3
	move.l	d2,d4
	move.l	d1,d0
	moveq	#1,d1
	move.w	#E_RETRYERROR,d2
	bsr	GetMem
	move.l	d0,a0
	tst.l	d0
	beq.w	RPL_1
	tst.l	resList(pc)
	bne	RPL_1a
	move.l	d0,resList
	clr.l	rl_prev(a0)
	bra.w	RPL_3
RPL_1a	move.l	resNext(pc),a1
	move.l	d0,rl_next(a1)
	move.l	a1,rl_prev(a0)
RPL_3	move.l	a0,resNext
	clr.l	rl_next(a0)
	move.w	d3,rl_type(a0)
	move.l	d4,rl_item(a0)
	bra.b	RPL_4
RPL_1	lea	RPL_errorMsg(pc),a0
	bsr	FatalError
RPL_4	move.l	d4,d2
	movem.l	(sp)+,a1/d3-d4
	rts

RPL_errorMsg	dc.b	'Not enough memory available.',0

;**********************************************************************

	cnop	0,4
	
	XDEF	_ActivateNewResource
	XDEF	@ActivateNewResource
	
_ActivateNewResource
@ActivateNewResource
ActivateNewResource:

	bsr	AllocResource
	bsr	ActivateResource
	rts

;**********************************************************************

	XDEF	_AllocResource
	XDEF	@AllocResource
	
_AllocResource
@AllocResource
AllocResource:

	movem.l	d1-d2/a0-a1,-(sp)
	moveq	#rma_SIZEOF,d0
	move.l	#MEMF_PUBLIC|MEMF_CLEAR,d1
	moveq	#E_FATALERROR,d2
	bsr	GetMem
	move.l	d0,a1
	moveq	#rma_SIZEOF,d0
	move.l	#MEMF_PUBLIC|MEMF_CLEAR,d1
	moveq	#E_FATALERROR,d2
	bsr	GetMem
	move.l	mainList(pc),a0
	tst.l	a0
	beq	AR_1
AR_1a	move.l	rma_next(a0),d1
	beq	AR_1b
	move.l	d1,a0
	bra	AR_1a
AR_1b	move.l	a0,rma_prev(a1)
	move.l	a1,rma_next(a0)
	bra	AR_2
AR_1	move.l	a1,mainList
AR_2	move.l	d0,rma_resList(a1)
	move.l	d0,a0
	move.w	#R_BLANK,rl_type(a0)
	movem.l	(sp)+,d1-d2/a0-a1
	rts

;**********************************************************************

	;d0	=	oldList

	XDEF	_RemoveResource
	XDEF	@RemoveResource
	
_RemoveResource
@RemoveResource
RemoveResource:

	movem.l	d1-d3/a0-a2/a6,-(sp)
	move.l	mainList(pc),a2
	tst.l	a2
	beq	RR_E
RR_1	cmp.l	rma_resList(a2),d0
	bne	RR_3
	move.l	resList(pc),d2
	move.l	resNext(pc),d3
	bsr	ActivateResource
	bsr	Res_FreeResource
	move.l	rma_prev(a2),a0
	move.l	rma_next(a2),a1
	tst.l	a1
	beq	RR_4
	move.l	a0,rma_prev(a1)
RR_4	tst.l	a0
	beq	RR_5
	move.l	a1,rma_next(a0)
RR_5	move.l	4.w,a6
	move.l	a2,a1
	moveq	#rma_SIZEOF,d0
	jsr	_LVOFreeMem(a6)
	move.l	d2,resList
	move.l	d3,resNext
	bra	RR_E
RR_3	move.l	rma_next(a2),a2
	tst.l	a2
	bne	RR_1
RR_E	movem.l	(sp)+,d1-d3/a0-a2/a6
	rts

;**********************************************************************

	;d0	=	actList
	
	XDEF	_ActivateResource
	XDEF	@ActivateResource
	
_ActivateResource
@ActivateResource
ActivateResource:

	movem.l	d0/a0,-(sp)
	move.l	mainList(pc),a0
	tst.l	a0
	beq	ARe_E
ARe_1	cmp.l	rma_resList(a0),d0
	bne	ARe_2
	move.l	rma_resList(a0),a0
	move.l	a0,resList
ARe_4	move.l	rl_next(a0),d0
	beq	ARe_3
	move.l	d0,a0
	bra	ARe_4
ARe_3	move.l	a0,resNext
	bra	ARe_E
ARe_2	move.l	rma_next(a0),a0
	tst.l	a0
	bne	ARe_1
ARe_E	movem.l	(sp)+,d0/a0
	rts

;**********************************************************************

	XDEF	_FreeAll
	XDEF	@FreeAll
	
_FreeAll
@FreeAll
FreeAll:

	movem.l	d0-d1/a0-a2/a6,-(sp)
	move.l	4.w,a6
	move.l	mainList(pc),a2
	tst.l	a2
	beq	FA_E
FA_1	move.l	rma_next(a2),d0
	beq	FA_2
	move.l	d0,a2
	bra	FA_1
FA_2	move.l	rma_resList(a2),d0
	bsr	ActivateResource
	bsr	Res_FreeResource
	move.l	a2,a1
	move.l	rma_prev(a1),a2
	moveq	#rma_SIZEOF,d0
	jsr	_LVOFreeMem(a6)
	tst.l	a2
	bne	FA_2
FA_E	movem.l	(sp)+,d0-d1/a0-a2/a6
	rts

;**********************************************************************

	XDEF	_Res_FreeResource
	XDEF	@Res_FreeResource
	
_Res_FreeResource
@Res_FreeResource
Res_FreeResource:

	movem.l	d0-d1/a0-a3/a6,-(sp)
	move.l	resNext(pc),a2
	lea	R_jmpTab(pc),a3
R_1	tst.l	a2
	beq	R_E
	move.l	4.w,a6
	move.w	rl_type(a2),d0
	move.l	(d0.w*4,a3),d0
R_jmp	jmp	(pc,d0.l)
R_mem	move.l	rl_item(a2),a1
	move.l	rm_memSize(a2),d0
	jsr	_LVOFreeMem(a6)
	moveq	#rmr_SIZEOF,d0
	bra	R_2
R_scr	move.l	_IntuitionBase(pc),a6
	move.l	rl_item(a2),a0
	jsr	_LVOCloseScreen(a6)
	moveq	#rl_SIZEOF,d0
	bra	R_2
R_lib	move.l	rl_item(a2),a1
	jsr	_LVOCloseLibrary(a6)
	moveq	#rl_SIZEOF,d0
	bra	R_2
R_bla	moveq	#rl_SIZEOF,d0
	bra	R_2
R_msg	move.l	rl_item(a2),a0
	jsr	_LVODeleteMsgPort(a6)
	moveq	#rl_SIZEOF,d0
	bra	R_2
R_ior	move.l	rl_item(a2),a0
	jsr	_LVODeleteIORequest(a6)
	moveq	#rl_SIZEOF,d0
	bra	R_2
R_dev	move.l	rd_checkFlag(a2),a1
	tst.b	(a1)
	beq	R_dev1
	move.l	rl_item(a2),a1
	jsr	_LVOCheckIO(a6)
	tst.l	d0
	bne	R_dev1
	move.l	rl_item(a2),a1
	jsr	_LVOAbortIO(a6)
	move.l	rl_item(a2),a1
	jsr	_LVOWaitIO(a6)
R_dev1	move.l	rl_item(a2),a1
	jsr	_LVOCloseDevice(a6)
	moveq	#rd_SIZEOF,d0
	bra	R_2
R_fun	move.l	rl_item(a2),a1
	jsr	(a1)
	moveq	#rl_SIZEOF,d0
	bra	R_2
R_vec	move.l	rl_item(a2),a1
	jsr	_LVOFreeVec(a6)
	moveq	#rl_SIZEOF,d0
	bra	R_2
R_sig	move.l	rl_item(a2),d0
	jsr	_LVOFreeSignal(a6)
	moveq	#rl_SIZEOF,d0
	bra	R_2
	
R_clo	move.l	rl_item(a2),d1
	move.l	_DOSBase(pc),a6
	jsr	_LVOClose(a6)
	moveq	#rl_SIZEOF,d0
	bra	R_2
	
R_2	move.l	a2,a1
	move.l	rl_prev(a1),a2
	move.l	4.w,a6
	jsr	_LVOFreeMem(a6)
	bra	R_1
R_E	movem.l	(sp)+,d0-d1/a0-a3/a6
	rts

R_jmpTab	dc.l	R_mem-R_jmp-2
		dc.l	R_scr-R_jmp-2
		dc.l	R_lib-R_jmp-2
		dc.l	R_bla-R_jmp-2
		dc.l	R_msg-R_jmp-2
		dc.l	R_ior-R_jmp-2
		dc.l	R_dev-R_jmp-2
		dc.l	R_fun-R_jmp-2
		dc.l	R_vec-R_jmp-2
		dc.l	R_sig-R_jmp-2
		dc.l	R_clo-R_jmp-2

;**********************************************************************
	
	cnop	0,4
	
	;d0	=	errorFlags
	;a0	=	errorMsg Ptr.
	;d0	=	return( 0=DON'T TRY AGAIN , 1=TRY AGAIN )

	XDEF	_ProduceError
	XDEF	@ProduceError
	
_ProduceError
@ProduceError
ProduceError:

	move.l	d1,-(sp)
	move.w	d0,d1
	andi.b	#E_NOTIFYERROR,d1
	beq	PE_1
	bsr	NotifyError
	moveq	#0,d0
	bra	PE_E
PE_1	move.w	d0,d1
	andi.b	#E_RETRYERROR,d1
	beq	PE_2
	bsr	RetryError
	bra	PE_E
PE_2	andi.b	#E_FATALERROR,d0
	beq	PE_3
	bsr	FatalError
PE_3	moveq	#0,d0
PE_E	move.l	(sp)+,d1
	rts
	
;**********************************************************************

	;a0	=	errorMsg
	;return	=	d0

	XDEF	_RetryError
	XDEF	@RetryError

_RetryError
@RetryError
RetryError:

	movem.l	d1/a1-a3/a6,-(sp)
	move.l	_IntuitionBase(pc),a6
	tst.l	a6
	beq	RE_E
	lea	RE_easy(pc),a1
	move.l	a0,12(a1)
	suba.l	a0,a0
	suba.l	a2,a2
	suba.l	a3,a3
	jsr	_LVOEasyRequestArgs(a6)
RE_E	movem.l	(sp)+,d1/a1-a3/a6
	rts
	
RE_easy		dc.l	20,0,RE_title,0,RE_msg
RE_title	dc.b	'Error',0
RE_msg		dc.b	'Retry|Cancel',0
	

;**********************************************************************

	cnop	0,4
	
	XDEF	_NotifyError
	XDEF	@NotifyError
	
_NotifyError
@NotifyError
NotifyError:

	movem.l	d1/a1-a3/a6,-(sp)
	move.l	_IntuitionBase(pc),a6
	tst.l	a6
	beq	NE_E
	lea	NE_easy(pc),a1
	move.l	a0,12(a1)
	suba.l	a0,a0
	suba.l	a2,a2
	suba.l	a3,a3
	jsr	_LVOEasyRequestArgs(a6)
NE_E	movem.l	(sp)+,d1/a1-a3/a6
	rts

NE_easy		dc.l	20,0,NE_title,0,NE_msg
NE_title	dc.b	'Message',0
NE_msg		dc.b	'OK',0


;**********************************************************************
	
	cnop	0,4
	
	XDEF	_FatalError
	XDEF	@FatalError
	
_FatalError
@FatalError
FatalError:

	movem.l	d0-d1/a1-a3/a6,-(sp)
	move.l	_IntuitionBase(pc),a6
	tst.l	a6
	beq	FE_1
	lea	FE_easy(pc),a1
	move.l	a0,12(a1)
	suba.l	a0,a0
	suba.l	a2,a2
	suba.l	a3,a3
	jsr	_LVOEasyRequestArgs(a6)
	bsr	FreeAll
FE_1	move.l	originalStack(pc),d0
	beq	FE_2
	move.l	d0,sp
	rts
FE_2	lea	FE_dosname(pc),a1
	moveq	#0,d0
	moveq	#E_RETRYERROR,d1
	bsr	R_OpenLibrary
	tst.l	d0
	beq	FE_3
	move.l	d0,a6
	moveq	#-1,d0
	jsr	_LVOExit(a6)
FE_3	movem.l	(sp)+,d0-d1/a1-a3/a6
	rts
	

FE_easy		dc.l	20,0,FE_title,0,FE_msg
FE_title	dc.b	'Fatal Error',0
FE_msg		dc.b	'OK',0
FE_dosname	dc.b	'dos.library',0

;**********************************************************************

	cnop	0,4

_DoSCSI
@DoSCSI	
DoSCSI

	;a0	=	IORequest
	;a1	=	Command
	;d0	=	CommandLength
	;a2	=	Buffer
	;d1	=	Length
	;d2	=	Flags
	;d3	=	Asynchronous
	;a3	=	ActivityName
	
DS_1	movem.l	d0-d7/a0-a6,-(sp)
	move.l	40(a0),a4
	move.l	a2,(a4)
	move.l	d1,4(a4)
	clr.l	8(a4)
	move.l	a1,12(a4)
	move.w	d0,16(a4)
	clr.w	18(a4)
	tst.l	22(a4)
	beq	DS_2
	ori.b	#$02,d2
DS_2	move.b	d2,20(a4)
	clr.b	21(a4)
	clr.w	28(a4)
	clr.b	30(a0)
	move.l	#30,36(a0)
	move.w	#28,28(a0)
	move.l	4.w,a6
	move.l	a0,a1
	tst.w	d3
	beq	DS_3
	jsr	_LVOSendIO(a6)
	bra	DS_E
DS_3	jsr	_LVODoIO(a6)
	tst.w	28(a4)
	beq	DS_E
	move.l	22(a4),a0
	lea	Req_SCSIArgs(pc),a1
	move.l	a3,(a1)
	move.l	a1,a3
	lea	SenseKeys(pc),a1
	moveq	#0,d0
	move.b	2(a0),d0
	andi.b	#$0f,d0
	move.l	(a1,d0.w*4),4(a3)
	lea	Req_AddName(pc),a1
	move.l	a1,8(a3)
	cmpi.b	#6,7(a0)
	bcs	DS_4
	lea	ErrorTable(pc),a1
	move.w	12(a0),d0
DS_5	cmp.w	(a1),d0
	beq	DS_5a
	cmpi.w	#$ffff,(a1)
	beq	DS_5a
	lea	6(a1),a1
	bra	DS_5
DS_5a	move.l	2(a1),8(a3)
DS_4	suba.l	a0,a0
	lea	Req_SCSIErr(pc),a1
	suba.l	a2,a2
	move.l	_IntuitionBase,a6
	jsr	_LVOEasyRequestArgs(a6)
	tst.l	d0
	beq	DS_E
	movem.l	(sp)+,d0-d7/a0-a6
	bra	DS_1
DS_E	move.l	8(a4),Scsi_Ret
	movem.l	(sp)+,d0-d7/a0-a6
	move.l	Scsi_Ret(pc),d0
	rts
	
Req_SCSIErr	dc.l	20,0,Req_SCSIt1,Req_SCSIt2,Req_SCSIt3
Req_SCSIArgs	dc.l	0,0,0,0
Req_SCSIt1	dc.b	'SCSI error',0
Req_SCSIt2	dc.b	'SCSI unit reports error while %s',$0a,'%s: %s',0
Req_SCSIt3	dc.b	'Retry|Cancel',0
Req_AddName	dc.b	'NO ADDITIONAL ERROR CODE',0
Scsi_Ret	dc.l	0

	cnop	0,4

SenseKeys	dc.l	sk1,sk2,sk3,sk4
		dc.l	sk5,sk6,sk7,sk8
		dc.l	sk9,sk10,sk11,12
		dc.l	sk13,sk14,sk15,sk16

sk1		dc.b	'NO SENSE',0
sk2		dc.b	'RECOVERED ERROR',0
sk3		dc.b	'NOT READY',0
sk4		dc.b	'MEDIUM ERROR',0
sk5		dc.b	'HARDWARE ERRROR',0
sk6		dc.b	'ILLEGAL REQUEST',0
sk7		dc.b	'UNIT ATTENTION',0
sk8		dc.b	'DATA PROTECT',0
sk9		dc.b	'BLANK CHECK',0
sk10		dc.b	'VENDOR-SPECIFIC',0
sk11		dc.b	'COPY ABORTED',0
sk12		dc.b	'ABORTED COMMAND',0
sk13		dc.b	'EQUAL',0
sk14		dc.b	'VOLUME OVERFLOW',0
sk15		dc.b	'MISCOMPARE',0
sk16		dc.b	'RESERVED',0

	cnop	0,4

ErrorTable

		dc.w	$1300
		dc.l	er1
		dc.w	$1200
		dc.l	er2
		dc.w	$0011
		dc.l	er3
		dc.w	$0012
		dc.l	er4
		dc.w	$0014
		dc.l	er5
		dc.w	$0013
		dc.l	er6
		dc.w	$0004
		dc.l	er7
		dc.w	$1404
		dc.l	er8
		dc.w	$3002
		dc.l	er9
		dc.w	$3001
		dc.l	er10
		dc.w	$5200
		dc.l	er11
		dc.w	$3F02
		dc.l	er12
		dc.w	$1106
		dc.l	er13
		dc.w	$3003
		dc.l	er14
		dc.w	$4A00
		dc.l	er15
		dc.w	$2C00
		dc.l	er16
		dc.w	$2F00
		dc.l	er17
		dc.w	$2B00
		dc.l	er18
		dc.w	$4100
		dc.l	er19
		dc.w	$4B00
		dc.l	er20
		dc.w	$1107
		dc.l	er21
		dc.w	$1600
		dc.l	er22
		dc.w	$1900
		dc.l	er23
		dc.w	$1903
		dc.l	er24
		dc.w	$1902
		dc.l	er25
		dc.w	$1901
		dc.l	er26
		dc.w	$1C00
		dc.l	er27
		dc.w	$3201
		dc.l	er28
		dc.w	$6300
		dc.l	er29
		dc.w	$0005
		dc.l	er30
		dc.w	$1403
		dc.l	er31
		dc.w	$0002
		dc.l	er32
		dc.w	$5100
		dc.l	er33
		dc.w	$0A00
		dc.l	er34
		dc.w	$1102
		dc.l	er35
		dc.w	$0302
		dc.l	er36
		dc.w	$3B07
		dc.l	er37
		dc.w	$3B06
		dc.l	er38
		dc.w	$0001
		dc.l	er39
		dc.w	$1402
		dc.l	er40
		dc.w	$0902
		dc.l	er41
		dc.w	$3101
		dc.l	er42
		dc.w	$5800
		dc.l	er43
		dc.w	$1C02
		dc.l	er44
		dc.w	$0006
		dc.l	er45
		dc.w	$1000
		dc.l	er46
		dc.w	$2200
		dc.l	er47
		dc.w	$6400
		dc.l	er48
		dc.w	$2801
		dc.l	er49
		dc.w	$3000
		dc.l	er50
		dc.w	$1108
		dc.l	er51
		dc.w	$4800
		dc.l	er52
		dc.w	$3F03
		dc.l	er53
		dc.w	$4400
		dc.l	er54
		dc.w	$3D00
		dc.l	er55
		dc.w	$2C02
		dc.l	er56
		dc.w	$2000
		dc.l	er57
		dc.w	$2101
		dc.l	er58
		dc.w	$2400
		dc.l	er59
		dc.w	$2600
		dc.l	er60
		dc.w	$4900
		dc.l	er61
		dc.w	$1105
		dc.l	er62
		dc.w	$6000
		dc.l	er63
		dc.w	$5B02
		dc.l	er64
		dc.w	$5B00
		dc.l	er65
		dc.w	$5B03
		dc.l	er66
		dc.w	$2A02
		dc.l	er67
		dc.w	$2100
		dc.l	er68
		dc.w	$0800
		dc.l	er69
		dc.w	$0802
		dc.l	er70
		dc.w	$0801
		dc.l	er71
		dc.w	$0500
		dc.l	er72
		dc.w	$4C00
		dc.l	er73
		dc.w	$3E00
		dc.l	er74
		dc.w	$0401
		dc.l	er75
		dc.w	$0400
		dc.l	er76
		dc.w	$0404
		dc.l	er77
		dc.w	$0402
		dc.l	er78
		dc.w	$0403
		dc.l	er79
		dc.w	$2500
		dc.l	er80
		dc.w	$1501
		dc.l	er81
		dc.w	$5300
		dc.l	er82
		dc.w	$3B0D
		dc.l	er83
		dc.w	$3100
		dc.l	er84
		dc.w	$3A00
		dc.l	er85
		dc.w	$5302
		dc.l	er86
		dc.w	$3B0E
		dc.l	er87
		dc.w	$4300
		dc.l	er88
		dc.w	$3F01
		dc.l	er89
		dc.w	$1D00
		dc.l	er90
		dc.w	$110A
		dc.l	er91
		dc.w	$2A01
		dc.l	er92
		dc.w	$0700
		dc.l	er93
		dc.w	$1103
		dc.l	er94
		dc.w	$0000
		dc.l	er95
		dc.w	$0015
		dc.l	er96
		dc.w	$3200
		dc.l	er97
		dc.w	$1109
		dc.l	er98
		dc.w	$0100
		dc.l	er99
		dc.w	$0600
		dc.l	er100
		dc.w	$0200
		dc.l	er101
		dc.w	$0301
		dc.l	er102
		dc.w	$2800
		dc.l	er103
		dc.w	$5A01
		dc.l	er104
		dc.w	$5A00
		dc.l	er105
		dc.w	$5A03
		dc.l	er106
		dc.w	$5A02
		dc.l	er107
		dc.w	$6102
		dc.l	er108
		dc.w	$4E00
		dc.l	er109
		dc.w	$2D00
		dc.l	er110
		dc.w	$3B05
		dc.l	er111
		dc.w	$1A00
		dc.l	er112
		dc.w	$2601
		dc.l	er113
		dc.w	$2602
		dc.l	er114
		dc.w	$2A00
		dc.l	er115
		dc.w	$0300
		dc.l	er116
		dc.w	$5002
		dc.l	er117
		dc.w	$3B0C
		dc.l	er118
		dc.w	$3B0B
		dc.l	er119
		dc.w	$1502
		dc.l	er120
		dc.w	$2900
		dc.l	er121
		dc.w	$4200
		dc.l	er122
		dc.w	$1C01
		dc.l	er123
		dc.w	$4000
		dc.l	er124
		dc.w	$1500
		dc.l	er125
		dc.w	$3B0A
		dc.l	er126
		dc.w	$3B09
		dc.l	er127
		dc.w	$1101
		dc.l	er128
		dc.w	$1401
		dc.l	er129
		dc.w	$1400
		dc.l	er130
		dc.w	$1802
		dc.l	er131
		dc.w	$1805
		dc.l	er132
		dc.w	$1705
		dc.l	er133
		dc.w	$1803
		dc.l	er134
		dc.w	$1801
		dc.l	er135
		dc.w	$1800
		dc.l	er136
		dc.w	$1804
		dc.l	er137
		dc.w	$1703
		dc.l	er138
		dc.w	$1700
		dc.l	er139
		dc.w	$1702
		dc.l	er140
		dc.w	$1701
		dc.l	er141
		dc.w	$1704
		dc.l	er142
		dc.w	$1706
		dc.l	er143
		dc.w	$1707
		dc.l	er144
		dc.w	$1E00
		dc.l	er145
		dc.w	$3B08
		dc.l	er146
		dc.w	$3600
		dc.l	er147
		dc.w	$3700
		dc.l	er148
		dc.w	$5C00
		dc.l	er149
		dc.w	$3900
		dc.l	er150
		dc.w	$6200
		dc.l	er151
		dc.w	$4700
		dc.l	er152
		dc.w	$5400
		dc.l	er153
		dc.w	$4500
		dc.l	er154
		dc.w	$3B00
		dc.l	er155
		dc.w	$0003
		dc.l	er156
		dc.w	$3B04
		dc.l	er157
		dc.w	$0903
		dc.l	er158
		dc.w	$5C02
		dc.l	er159
		dc.w	$5C01
		dc.l	er160
		dc.w	$1B00
		dc.l	er161
		dc.w	$5500
		dc.l	er162
		dc.w	$3300
		dc.l	er163
		dc.w	$3B03
		dc.l	er164
		dc.w	$3B01
		dc.l	er165
		dc.w	$3B02
		dc.l	er166
		dc.w	$3F00
		dc.l	er167
		dc.w	$5B01
		dc.l	er168
		dc.w	$2603
		dc.l	er169
		dc.w	$2C01
		dc.l	er170
		dc.w	$0900
		dc.l	er171
		dc.w	$0901
		dc.l	er172
		dc.w	$6101
		dc.l	er173
		dc.w	$5700
		dc.l	er174
		dc.w	$5301
		dc.l	er175
		dc.w	$1100
		dc.l	er176
		dc.w	$1104
		dc.l	er177
		dc.w	$110B
		dc.l	er178
		dc.w	$110C
		dc.l	er179
		dc.w	$4600
		dc.l	er180
		dc.w	$5900
		dc.l	er181
		dc.w	$6100
		dc.l	er182
		dc.w	$5000
		dc.l	er183
		dc.w	$5001
		dc.l	er184
		dc.w	$0C00
		dc.l	er185
		dc.w	$0C02
		dc.l	er186
		dc.w	$0C01
		dc.l	er187
		dc.w	$2700
		dc.l	er188
		dc.w	$FFFF
		dc.l	er188

er1		dc.b	'ADDRESS MARK NOT FOUND FOR DATA FIELD',0
er2		dc.b	'ADDRESS MARK NOT FOUND FOR ID FIELD',0
er3		dc.b	'AUDIO PLAY OPERATION IN PROGRESS',0
er4		dc.b	'AUDIO PLAY OPERATION PAUSED',0
er5		dc.b	'AUDIO PLAY OPERATION STOPPED DUE TO ERROR',0
er6		dc.b	'AUDIO PLAY OPERATION SUCCESSFULLY COMPLETED',0
er7		dc.b	'BEGINNING-OF-PARTITION/MEDIUM DETECTED',0
er8		dc.b	'BLOCK SEQUENCE ERROR',0
er9		dc.b	'CANNOT READ MEDIUM - INCOMPATIBLE FORMAT',0
er10		dc.b	'CANNOT READ MEDIUM - UNKNOWN FORMAT',0
er11		dc.b	'CARTRIDGE FAULT',0
er12		dc.b	'CHANGED OPERATING DEFINITION',0
er13		dc.b	'CIRC UNRECOVERED ERROR',0
er14		dc.b	'CLEANING CARTRIDGE INSTALLED',0
er15		dc.b	'COMMAND PHASE ERROR',0
er16		dc.b	'COMMAND SEQUENCE ERROR',0
er17		dc.b	'COMMANDS CLEARED BY ANOTHER INITIATOR',0
er18		dc.b	'COPY CANNOT EXECUTE SINCE HOST CANNOT DISCONNECT',0
er19		dc.b	'DATA PATH FAILURE',0
er20		dc.b	'DATA PHASE ERROR',0
er21		dc.b	'DATA RESYCHRONIZATION ERROR',0
er22		dc.b	'DATA SYNCHRONIZATION MARK ERROR',0
er23		dc.b	'DEFECT LIST ERROR',0
er24		dc.b	'DEFECT LIST ERROR IN GROWN LIST',0
er25		dc.b	'DEFECT LIST ERROR IN PRIMARY LIST',0
er26		dc.b	'DEFECT LIST NOT AVAILABLE',0
er27		dc.b	'DEFECT LIST NOT FOUND',0
er28		dc.b	'DEFECT LIST UPDATE FAILURE',0
er29		dc.b	'END OF USER AREA ENCOUNTERED ON THIS TRACK',0
er30		dc.b	'END-OF-DATA DETECTED',0
er31		dc.b	'END-OF-DATA NOT FOUND',0
er32		dc.b	'END-OF-PARTITION/MEDIUM DETECTED',0
er33		dc.b	'ERASE FAILURE',0
er34		dc.b	'ERROR LOG OVERFLOW',0
er35		dc.b	'ERROR TOO LONG TO CORRECT',0
er36		dc.b	'EXCESSIVE WRITE ERRORS',0
er37		dc.b	'FAILED TO SENSE BOTTOM-OF-FORM',0
er38		dc.b	'FAILED TO SENSE TOP-OF-FORM',0
er39		dc.b	'FILEMARK DETECTED',0
er40		dc.b	'FILEMARK OR SETMARK NOT FOUND',0
er41		dc.b	'FOCUS SERVO FAILURE',0
er42		dc.b	'FORMAT COMMAND FAILED',0
er43		dc.b	'GENERATION DOES NOT EXIST',0
er44		dc.b	'GROWN DEFECT LIST NOT FOUND',0
er45		dc.b	'I/O PROCESS TERMINATED',0
er46		dc.b	'ID CRC OR ECC ERROR',0
er47		dc.b	'ILLEGAL FUNCTION',0
er48		dc.b	'ILLEGAL MODE FOR THIS TRACK',0
er49		dc.b	'IMPORT OR EXPORT ELEMENT ACCESSED',0
er50		dc.b	'INCOMPATIBLE MEDIUM INSTALLED',0
er51		dc.b	'INCOMPLETE BLOCK READ',0
er52		dc.b	'INITIATOR DETECTED ERROR MESSAGE RECEIVED',0
er53		dc.b	'INQUIRY DATA HAS CHANGED',0
er54		dc.b	'INTERNAL TARGET FAILURE',0
er55		dc.b	'INVALID BITS IN IDENTIFY MESSAGE',0
er56		dc.b	'INVALID COMBINATION OF WINDOWS SPECIFIED',0
er57		dc.b	'INVALID COMMAND OPERATION CODE',0
er58		dc.b	'INVALID ELEMENT ADDRESS',0
er59		dc.b	'INVALID FIELD IN CDB',0
er60		dc.b	'INVALID FIELD IN PARAMETER LIST',0
er61		dc.b	'INVALID MESSAGE ERROR',0
er62		dc.b	'L-EC UNCORRECTABLE ERROR',0
er63		dc.b	'LAMP FAILURE',0
er64		dc.b	'LOG COUNTER AT MAXIMUM',0
er65		dc.b	'LOG EXCEPTION',0
er66		dc.b	'LOG LIST CODES EXHAUSTED',0
er67		dc.b	'LOG PARAMETERS CHANGED',0
er68		dc.b	'LOGICAL BLOCK ADDRESS OUT OF RANGE',0
er69		dc.b	'LOGICAL UNIT COMMUNICATION FAILURE',0
er70		dc.b	'LOGICAL UNIT COMMUNICATION PARITY ERROR',0
er71		dc.b	'LOGICAL UNIT COMMUNICATION TIME-OUT',0
er72		dc.b	'LOGICAL UNIT DOES NOT RESPOND TO SELECTION',0
er73		dc.b	'LOGICAL UNIT FAILED SELF-CONFIGURATION',0
er74		dc.b	'LOGICAL UNIT HAS NOT SELF-CONFIGURED YET',0
er75		dc.b	'LOGICAL UNIT IS IN PROCESS OF BECOMING READY',0
er76		dc.b	'LOGICAL UNIT NOT READY, CAUSE NOT REPORTABLE',0
er77		dc.b	'LOGICAL UNIT NOT READY, FORMAT IN PROGRESS',0
er78		dc.b	'LOGICAL UNIT NOT READY, INITIALIZING COMMAND REQUIRED',0
er79		dc.b	'LOGICAL UNIT NOT READY, MANUAL INTERVENTION REQUIRED',0
er80		dc.b	'LOGICAL UNIT NOT SUPPORTED',0
er81		dc.b	'MECHANICAL POSITIONING ERROR',0
er82		dc.b	'MEDIA LOAD OR EJECT FAILED',0
er83		dc.b	'MEDIUM DESTINATION ELEMENT FULL',0
er84		dc.b	'MEDIUM FORMAT CORRUPTED',0
er85		dc.b	'MEDIUM NOT PRESENT',0
er86		dc.b	'MEDIUM REMOVAL PREVENTED',0
er87		dc.b	'MEDIUM SOURCE ELEMENT EMPTY',0
er88		dc.b	'MESSAGE ERROR',0
er89		dc.b	'MICROCODE HAS BEEN CHANGED',0
er90		dc.b	'MISCOMPARE DURING VERIFY OPERATION',0
er91		dc.b	'MISCORRECTED ERROR',0
er92		dc.b	'MODE PARAMETERS CHANGED',0
er93		dc.b	'MULTIPLE PERIPHERAL DEVICES SELECTED',0
er94		dc.b	'MULTIPLE READ ERRORS',0
er95		dc.b	'NO ADDITIONAL SENSE INFORMATION',0
er96		dc.b	'NO CURRENT AUDIO STATUS TO RETURN',0
er97		dc.b	'NO DEFECT SPARE LOCATION AVAILABLE',0
er98		dc.b	'NO GAP FOUND',0
er99		dc.b	'NO INDEX/SECTOR SIGNAL',0
er100		dc.b	'NO REFERENCE POSITION FOUND',0
er101		dc.b	'NO SEEK COMPLETE',0
er102		dc.b	'NO WRITE CURRENT',0
er103		dc.b	'NOT READY TO READY TRANSITION (MEDIUM MAY HAVE CHANGED)',0
er104		dc.b	'OPERATOR MEDIUM REMOVAL REQUEST',0
er105		dc.b	'OPERATOR REQUEST OR STATE CHANGE INPUT (UNSPECIFIED)',0
er106		dc.b	'OPERATOR SELECTED WRITE PERMIT',0
er107		dc.b	'OPERATOR SELECTED WRITE PROTECT',0
er108		dc.b	'OUT OF FOCUS',0
er109		dc.b	'OVERLAPPED COMMANDS ATTEMPTED',0
er110		dc.b	'OVERWRITE ERROR ON UPDATE IN PLACE',0
er111		dc.b	'PAPER JAM',0
er112		dc.b	'PARAMETER LIST LENGTH ERROR',0
er113		dc.b	'PARAMETER NOT SUPPORTED',0
er114		dc.b	'PARAMETER VALUE INVALID',0
er115		dc.b	'PARAMETERS CHANGED',0
er116		dc.b	'PERIPHERAL DEVICE WRITE FAULT',0
er117		dc.b	'POSITION ERROR RELATED TO TIMING',0
er118		dc.b	'POSITION PAST BEGINNING OF MEDIUM',0
er119		dc.b	'POSITION PAST END OF MEDIUM',0
er120		dc.b	'POSITIONING ERROR DETECTED BY READ OF MEDIUM',0
er121		dc.b	'POWER ON, RESET, OR BUS DEVICE RESET OCCURRED',0
er122		dc.b	'POWER-ON OR SELF-TEST FAILURE',0
er123		dc.b	'PRIMARY DEFECT LIST NOT FOUND',0
er124		dc.b	'RAM FAILURE',0
er125		dc.b	'RANDOM POSITIONING ERROR',0
er126		dc.b	'READ PAST BEGINNING OF MEDIUM',0
er127		dc.b	'READ PAST END OF MEDIUM',0
er128		dc.b	'READ RETRIES EXHAUSTED',0
er129		dc.b	'RECORD NOT FOUND',0
er130		dc.b	'RECORDED ENTITY NOT FOUND',0
er131		dc.b	'RECOVERED DATA - DATA AUTO-REALLOCATED',0
er132		dc.b	'RECOVERED DATA - RECOMMEND REASSIGNMENT',0
er133		dc.b	'RECOVERED DATA USING PREVIOUS SECTOR ID',0
er134		dc.b	'RECOVERED DATA WITH CIRC',0
er135		dc.b	'RECOVERED DATA WITH ERROR CORRECTION AND RETRIES APPLIED',0
er136		dc.b	'RECOVERED DATA WITH ERROR CORRECTION APPLIED',0
er137		dc.b	'RECOVERED DATA WITH LEC',0
er138		dc.b	'RECOVERED DATA WITH NEGATIVE HEAD OFFSET',0
er139		dc.b	'RECOVERED DATA WITH NO ERROR CORRECTION APPLIED',0
er140		dc.b	'RECOVERED DATA WITH POSITIVE HEAD OFFSET',0
er141		dc.b	'RECOVERED DATA WITH RETRIES',0
er142		dc.b	'RECOVERED DATA WITH RETRIES AND/OR CIRC APPLIED',0
er143		dc.b	'RECOVERED DATA WITHOUT ECC - DATA AUTO-REALLOCATED',0
er144		dc.b	'RECOVERED DATA WITHOUT ECC - RECOMMEND REASSIGNMENT',0
er145		dc.b	'RECOVERED ID WITH ECC CORRECTION',0
er146		dc.b	'REPOSITION ERROR',0
er147		dc.b	'RIBBON, INK, OR TONER FAILURE',0
er148		dc.b	'ROUNDED PARAMETER',0
er149		dc.b	'RPL STATUS CHANGE',0
er150		dc.b	'SAVING PARAMETERS NOT SUPPORTED',0
er151		dc.b	'SCAN HEAD POSITIONING ERROR',0
er152		dc.b	'SCSI PARITY ERROR',0
er153		dc.b	'SCSI TO HOST SYSTEM INTERFACE FAILURE',0
er154		dc.b	'SELECT OR RESELECT FAILURE',0
er155		dc.b	'SEQUENTIAL POSITIONING ERROR',0
er156		dc.b	'SETMARK DETECTED',0
er157		dc.b	'SLEW FAILURE',0
er158		dc.b	'SPINDLE SERVO FAILURE',0
er159		dc.b	'SPINDLES NOT SYNCHRONIZED',0
er160		dc.b	'SPINDLES SYNCHRONIZED',0
er161		dc.b	'SYNCHRONOUS DATA TRANSFER ERROR',0
er162		dc.b	'SYSTEM RESOURCE FAILURE',0
er163		dc.b	'TAPE LENGTH ERROR',0
er164		dc.b	'TAPE OR ELECTRONIC VERTICAL FORMS UNIT NOT READY',0
er165		dc.b	'TAPE POSITION ERROR AT BEGINNING-OF-MEDIUM',0
er166		dc.b	'TAPE POSITION ERROR AT END-OF-MEDIUM',0
er167		dc.b	'TARGET OPERATING CONDITIONS HAVE CHANGED',0
er168		dc.b	'THRESHOLD CONDITION MET',0
er169		dc.b	'THRESHOLD PARAMETERS NOT SUPPORTED',0
er170		dc.b	'TOO MANY WINDOWS SPECIFIED',0
er171		dc.b	'TRACK FOLLOWING ERROR',0
er172		dc.b	'TRACKING SERVO FAILURE',0
er173		dc.b	'UNABLE TO ACQUIRE VIDEO',0
er174		dc.b	'UNABLE TO RECOVER TABLE-OF-CONTENTS',0
er175		dc.b	'UNLOAD TAPE FAILURE',0
er176		dc.b	'UNRECOVERED READ ERROR',0
er177		dc.b	'UNRECOVERED READ ERROR - AUTO REALLOCATE FAILED',0
er178		dc.b	'UNRECOVERED READ ERROR - RECOMMEND REASSIGNMENT',0
er179		dc.b	'UNRECOVERED READ ERROR - RECOMMEND REWRITE THE DATA',0
er180		dc.b	'UNSUCCESSFUL SOFT RESET',0
er181		dc.b	'UPDATED BLOCK READ',0
er182		dc.b	'VIDEO ACQUISITION ERROR',0
er183		dc.b	'WRITE APPEND ERROR',0
er184		dc.b	'WRITE APPEND POSITION ERROR',0
er185		dc.b	'WRITE ERROR',0
er186		dc.b	'WRITE ERROR - AUTO REALLOCATION FAILED',0
er187		dc.b	'WRITE ERROR RECOVERED WITH AUTO REALLOCATION',0
er188		dc.b	'WRITE PROTECTED',0
er189		dc.b	'UNKNOWN ERROR CODE',0


	section resource_data,bss
	
textArea	ds.b	200
textAreaB	ds.b	100

OldModePage	ds.b	12