
gg****************************************************************************
	SECTION	backstablibrary000000,CODE
ProgStart:
	MOVEQ	#-1,D0
	RTS

lbC000004:
	ILLEGAL
	dc.l	lbC000004
	dc.l	lbW000A0E
	dc.w	$8001,$900
	dc.l	backstablibra
	dc.l	backstablibra0
	dc.l	lbL00005C
	dc.b	'$VER: backstab.library version 1.0 by Sami V'
	dc.b	'aarala in 6.12.93',0
lbL00005C:
	dc.l	$2C
	dc.l	lbL00006C
	dc.l	lbL00009C
	dc.l	lbC0000C8
lbL00006C:
	dc.l	lbC000156
	dc.l	lbC000164
	dc.l	lbC000178
	dc.l	lbC0001E2
	dc.l	r_takeover
	dc.l	r_return
	dc.l	r_activate
	dc.l	r_deactivate
	dc.l	lbC0003AA
	dc.l	lbC0003AE
	dc.l	lbC0003E4,$FFFFFFFF
lbL00009C:
	dc.l	$E0000008,$900C000
	dc.w	10
	dc.l	backstablibra
	dc.w	$E000,14,$600,$D000,$14,1,$D000,$16,0,$C000,$18
	dc.l	backstablibra0
	dcb.w	$2,0

lbC0000C8:
	MOVE.L	A5,-(SP)
	MOVEA.L	D0,A5
	MOVE.L	A6,2(A5)
	MOVE.L	A0,6(A5)
	MOVE.L	#$400,D0
	MOVEQ	#0,D1
	JSR	-$C6(A6)
	MOVE.L	D0,zero_copy
	BEQ.S	lbC00013C
	MOVEA.L	4,A6
	LEA	doslibrary0(PC),A1
	MOVEQ	#0,D0
	JSR	-$228(A6)
	MOVE.L	D0,lbL0007E6
	BEQ.L	lbC00013C
	LEA	intuitionlibr(PC),A1
	MOVEQ	#0,D0
	JSR	-$228(A6)
	MOVE.L	D0,int_base
	BEQ.L	lbC000134
	LEA	graphicslibra(PC),A1
	MOVEQ	#0,D0
	JSR	-$228(A6)
	MOVE.L	D0,lbL0007EA
	BEQ.S	lbC00012C
	MOVE.L	A5,D0
	MOVEA.L	(SP)+,A5
	RTS

lbC00012C:
	MOVEA.L	int_base(PC),A1
	JSR	-$19E(A6)
lbC000134:
	MOVEA.L	lbL0007E6(PC),A1
	JSR	-$19E(A6)
lbC00013C:
	MOVEQ	#-1,D0
lbC00013E:
	MOVE.W	#$F00,$DFF180
	MOVE.W	#$FF0,$DFF180
	DBRA	D0,lbC00013E
	MOVEQ	#0,D0
	RTS

lbC000156:
	ADDQ.W	#1,$20(A6)
	BCLR	#3,0(A6)
	MOVE.L	A6,D0
	RTS

lbC000164:
	SUBQ.W	#1,$20(A6)
	BNE.S	lbC000174
	BTST	#3,0(A6)
	BEQ.S	lbC000174
	BSR.S	lbC000178
lbC000174:
	MOVEQ	#0,D0
	RTS

lbC000178:
	MOVE.L	A5,-(SP)
	MOVEA.L	A6,A5
	MOVEA.L	2(A5),A6
	TST.W	$20(A5)
	BEQ.S	lbC000194
	BSET	#3,0(A5)
	MOVEA.L	A5,A6
	MOVEA.L	(SP)+,A5
	MOVEQ	#0,D0
	RTS

lbC000194:
	MOVEA.L	zero_copy(PC),A1
	MOVE.L	#$400,D0
	JSR	-$D2(A6)
	MOVEA.L	lbL0007E6(PC),A1
	JSR	-$19E(A6)
	MOVEA.L	int_base(PC),A1
	JSR	-$19E(A6)
	MOVEA.L	lbL0007EA(PC),A1
	JSR	-$19E(A6)
	MOVE.L	D2,-(SP)
	MOVE.L	6(A5),D2
	MOVEA.L	A5,A1
	JSR	-$FC(A6)
	MOVEQ	#0,D0
	MOVEA.L	A5,A1
	MOVE.W	$10(A5),D0
	SUBA.L	D0,A1
	ADD.W	$12(A5),D0
	JSR	-$D2(A6)
	MOVE.L	D2,D0
	MOVE.L	(SP)+,D2
	MOVEA.L	A5,A6
	MOVEA.L	(SP)+,A5
	RTS

lbC0001E2:
	MOVEQ	#0,D0
	RTS

no_audio:
	MOVEQ	#-1,D0
	MOVEA.L	(SP)+,A6
	RTS

r_takeover:
	MOVE.L	D0,flags
	MOVE.L	A6,-(SP)
	move.l	4.w,a6		;New client! Task pointer to 'aud_task'
	sub.l	a1,a1		;(*in* the audio device structure)
	JSR	-$126(A6)	;FindTask
	MOVE.L	D0,aud_task
	move.l	d0,a1		;Set task priority as high as possible
	moveq	#127,d0		;to prevent someone running with us
	JSR	-$12C(A6)	;set task pri
	MOVE.L	D0,old_taskpri
	BSR.L	alloc_audio
	BEQ.S	no_audio

	LEA	$DFF096,A0	; disable audio
	MOVEQ	#0,D0
	MOVE.W	D0,$12(A0)
	MOVE.W	D0,$22(A0)
	MOVE.W	D0,$32(A0)
	MOVE.W	D0,$42(A0)
	MOVE.W	#15,(A0)

	MOVEA.L	4.w,A6
	JSR	-$78(A6)	; Disable

	CLR.L	old_vbr
	CLR.L	chip_stores
	CLR.L	chip_stores4
	BTST	#1,$129(A6)	; check 68020+
	BNE.S	check_nocache
	BCLR	#0,flags+3
check_nocache:
	BTST	#0,flags+3
	BEQ.S	nocache_ok
	MOVE.W	$14(A6),D0	; lib_version
	CMPI.W	#37,D0		; kick2+?
	BHS.S	nocache_ok
	MOVEA.L	int_base(PC),A6
	MOVEQ	#0,D0
	LEA	cache_alert(PC),A0
	MOVEQ	#$3C,D1
	JSR	-$5A(A6)	; Displayalert
	TST.L	D0
	BNE.S	nocache_ok
	MOVEQ	#-2,D0		; error code
	RTS

nocache_ok:
	BSR.W	reset_gfx
	MOVEA.L	4.w,A6
	JSR	-$96(A6)	; Superstate
	MOVE.L	D0,oldsysstack
	MOVEQ	#0,D0
	BTST	#0,$129(A6)	; 68010?
	BEQ.S	vbr_68000
	movec	vbr,d0
vbr_68000:
	MOVE.L	D0,-(SP)
	MOVE.L	oldsysstack(PC),D0
	JSR	-$9C(A6)	; userstate
	MOVEA.L	(SP)+,A1
	MOVEA.L	zero_copy(PC),A0
	MOVE.W	#[$400/4]-1,D0
Fill:
	MOVE.L	(A1)+,(A0)+
	DBRA	D0,Fill
	BRA.S	cp_takeover

r_deactivate:
	;Flags are the same as TakeOver() [still stored]
	MOVE.L	A6,-(SP)
	MOVEA.L	4.w,A6
	JSR	-$78(A6)	; Disable
cp_takeover:
	BSR.L	wait_devices
	BSR.L	own_blitter
	BSR.L	reset_caches
	MOVEA.L	4.w,A6
	JSR	-$96(A6)	; superstate
	MOVE.L	D0,oldsysstack
	BSR.L	swap_zeropage_and_vbr
	BTST	#1,flags+3
	BNE.S	nouser
	MOVEA.L	4.w,A6
	MOVE.L	oldsysstack(PC),D0
	JSR	-$9C(A6)	; userstate
nouser:
	BSR.w	swap_chipregs
	BSR.w	get_return_data
	MOVEA.L	(SP)+,A6
	MOVEQ	#0,D0
	RTS

	MOVEA.L	(SP)+,A6
	MOVEQ	#-2,D0
	RTS

r_activate:
	MOVE.L	D2,-(SP)
	MOVEQ	#0,D2
	BRA.S	common_activation

r_return:
	MOVE.L	D2,-(SP)
	MOVEQ	#-1,D2
common_activation:
	;This piece of code is almost similar to 'ActivateSystem' and 'Return-
	;ToSystem'. The only difference is that ReturnToSystem frees audio
	;channels and restores gfx. To optimize size, D2 indicates which case
	;are we running, and some things are bypassed if it isn't ReturnTo-
	;System..

	move.l	a6,-(sp)		;
	move.w	#$4000,$dff09a		;Disable interrupts
	bsr.w	swap_chipregs		;Chip handling
	btst	#1,flags+3		;If SUPERVISOR flag wasn't set, we have
	BNE.S	was_super
	MOVEA.L	4.w,A6
	JSR	-$96(A6)	; superstate
	MOVE.L	D0,oldsysstack
was_super:
	BSR.w	swap_zeropage_and_vbr
	MOVEA.L	4.w,A6
	MOVE.L	oldsysstack(PC),D0
	JSR	-$9C(A6)	; Userstate
	BSR.w	restore_caches
	BSR.w	disown_blitter
	tst.w	d2			;System view back (if ReturnToSystem)
	BEQ.S	only_in_return1
	BSR.w	restore_gfx
only_in_return1:
	MOVEA.L	4.w,A6
	JSR	-$7E(A6)		; Enable
	tst.w	d2			;Audio chans back (if ReturnToSystem)
	BEQ.S	only_in_return2
	LEA	$DFF096,A0		; reset audio
	MOVEQ	#0,D0
	MOVE.W	D0,$12(A0)
	MOVE.W	D0,$22(A0)
	MOVE.W	D0,$32(A0)
	MOVE.W	D0,$42(A0)
	MOVE.W	#15,(A0)
	BSR.w	restore_audio
	move.l	4.w,a6			;Task priority back
	MOVEA.L	aud_task(PC),A1
	MOVE.L	old_taskpri(PC),D0
	JSR	-$12C(A6)		; set task pri
only_in_return2:
	MOVEA.L	(SP)+,A6
	MOVE.L	(SP)+,D2
	RTS

lbC0003AA:
	BRA.L	r_takeover

lbC0003AE:
	MOVEA.L	4,A6
	CMPI.W	#$24,$14(A6)
	BLT.S	lbC0003BE
	JMP	-$2D6(A6)

lbC0003BE:
	MOVE.W	#$4000,$DFF09A
	LEA	lbC0003D0(PC),A5
	JSR	-$1E(A6)
	dc.w	$FFFF
lbC0003D0:
	LEA	$1000000,A0
	SUBA.L	-$14(A0),A0
	MOVEA.L	4(A0),A0
	SUBQ.L	#2,A0
	RESET
	JMP	(A0)

lbC0003E4:
	MOVE.L	A6,-(SP)
	MOVEA.L	4,A6
	MOVE.W	$14(A6),D0
	CMPI.W	#$25,D0
	BLO.S	lbC0003FE
	JSR	-$27C(A6)
	MOVEA.L	(SP)+,A6
	MOVEQ	#0,D0
	RTS

lbC0003FE:
	MOVEA.L	(SP)+,A6
	MOVEQ	#-1,D0
	RTS

get_return_data:
	MOVEQ	#0,D1
	MOVEA.L	4,A6
	CMPI.W	#$24,$14(A6)
	BLO.S	lbC00042C
	MOVEA.L	lbL0007EA(PC),A6
	BTST	#2,$EC(A6)
	BNE.S	lbC00042A
	BTST	#1,$EC(A6)
	BEQ.S	lbC00042C
	MOVEQ	#1,D1
	BRA.S	lbC00042C

lbC00042A:
	MOVEQ	#2,D1
lbC00042C:
	MOVEA.L	4,A6
	MOVEQ	#0,D2
	MOVE.W	$14(A6),D2
	MOVE.W	$128(A6),D0
	BTST	#3,D0
	BNE.S	lbC000462
	BTST	#2,D0
	BNE.S	lbC00045E
	BTST	#1,D0
	BNE.S	lbC00045A
	BTST	#0,D0
	BNE.S	lbC000456
	MOVEQ	#0,D3
	BRA.S	lbC000464

lbC000456:
	MOVEQ	#1,D3
	BRA.S	lbC000464

lbC00045A:
	MOVEQ	#2,D3
	BRA.S	lbC000464

lbC00045E:
	MOVEQ	#3,D3
	BRA.S	lbC000464

lbC000462:
	MOVEQ	#4,D3
lbC000464:
	MOVEQ	#0,D4
	LSR.W	#4,D0
	ANDI.W	#7,D0
	MOVE.W	D0,D4
	RTS

reset_caches:
	CLR.L	lbL000806
	BTST	#0,flags3
	BEQ.S	lbC00049E
	MOVEA.L	4,A6
	JSR	-$27C(A6)
	MOVEQ	#0,D0
	MOVEQ	#0,D1
	JSR	-$288(A6)
	MOVE.L	D0,lbL000806
	MOVE.L	D0,D1
	MOVEQ	#0,D0
	JSR	-$288(A6)
lbC00049E:
	RTS

restore_caches:
	MOVE.L	lbL000806(PC),D0
	BEQ.S	lbC0004B4
	MOVEA.L	4,A6
	MOVE.L	lbL000806(PC),D0
	MOVE.L	D0,D1
	JSR	-$288(A6)
lbC0004B4:
	RTS

alloc_audio:
	CLR.B	lbB000812
	MOVEQ	#-1,D0
	JSR	-$14A(A6)
	MOVE.B	D0,lbB0007B7
	BMI.S	lbC000504
	LEA	lbL0007A8(PC),A1
	JSR	-$162(A6)
	TST.L	D0
	BEQ.S	lbC0004FA
	LEA	audiodevice(PC),A0
	MOVEQ	#0,D0
	LEA	lbL000764(PC),A1
	MOVEQ	#0,D1
	JSR	-$1BC(A6)
	TST.L	D0
	BNE.S	lbC0004F2
	NOT.B	lbB000812
	RTS

lbC0004F2:
	LEA	lbL0007A8(PC),A1
	JSR	-$168(A6)
lbC0004FA:
	MOVEQ	#0,D0
	MOVE.B	lbB0007B7(PC),D0
	JSR	-$150(A6)
lbC000504:
	MOVEA.L	int_base(PC),A6
	MOVEQ	#0,D0
	LEA	cache_alert0(PC),A0
	MOVEQ	#$3C,D1
	JSR	-$5A(A6)
	TST.L	D0
	RTS

restore_audio:
	TST.B	lbB000812
	BEQ.S	lbC00053E
	MOVEA.L	4,A6
	LEA	lbL000764(PC),A1
	JSR	-$1C2(A6)
	LEA	lbL0007A8(PC),A1
	JSR	-$168(A6)
	MOVEQ	#0,D0
	MOVE.B	lbB0007B7(PC),D0
	JSR	-$150(A6)
lbC00053E:
	RTS

wait_devices:
	RTS

reset_gfx:
	SUBA.L	A1,A1
	JSR	-$126(A6)
	MOVEA.L	D0,A1
	CLR.L	lbL0007CE
	MOVEA.L	4,A6
	MOVE.W	$14(A6),D0
	CMPI.W	#$27,D0
	BLO.L	lbC0005E4
	MOVE.L	#$80000032,lbL0007D2
	MOVE.L	#0,lbL0007D6
	MOVEA.L	int_base(PC),A6
	LEA	Workbench(PC),A0
	JSR	-$1FE(A6)
	MOVE.L	D0,lbL0007CE
	BEQ.S	lbC0005E4
	MOVEA.L	D0,A0
	MOVEA.L	$30(A0),A0
	LEA	lbL0007D2(PC),A1
	MOVEA.L	lbL0007EA(PC),A6
	JSR	-$2C4(A6)
	MOVE.L	lbL0007D6,lbL0007CA
	MOVE.L	#$80000031,lbL0007D2
	MOVE.L	#1,lbL0007D6
	MOVEA.L	lbL0007CE(PC),A0
	MOVEA.L	$30(A0),A0
	LEA	lbL0007D2(PC),A1
	JSR	-$2C4(A6)
	MOVEA.L	lbL0007CE(PC),A0
	MOVEA.L	int_base(PC),A6
	JSR	-$17A(A6)
	JSR	-$186(A6)
	MOVEA.L	lbL0007EA(PC),A6
	JSR	-$10E(A6)
	JSR	-$10E(A6)
lbC0005E4:
	MOVEA.L	lbL0007EA(PC),A6
	MOVE.L	$22(A6),lbL0007FE
	SUBA.L	A1,A1
	JSR	-$DE(A6)
	JSR	-$10E(A6)
	JMP	-$10E(A6)

restore_gfx:
	MOVE.L	lbL0007CE(PC),D0
	BEQ.S	lbC000638
	MOVEA.L	D0,A0
	MOVE.L	lbL0007CA(PC),lbL0007D6
	LEA	lbL0007D2(PC),A1
	MOVEA.L	$30(A0),A0
	MOVEA.L	lbL0007EA(PC),A6
	JSR	-$2C4(A6)
	MOVEA.L	int_base(PC),A6
	MOVEA.L	lbL0007CE(PC),A0
	JSR	-$17A(A6)
	MOVEA.L	lbL0007CE(PC),A1
	SUBA.L	A0,A0
	JSR	-$204(A6)
	MOVEA.L	lbL0007EA(PC),A6
lbC000638:
	MOVEA.L	lbL0007EA(PC),A6
	MOVEA.L	lbL0007FE(PC),A1
	JSR	-$DE(A6)
	JSR	-$10E(A6)
	JSR	-$10E(A6)
	MOVE.L	$26(A6),$DFF080
	MOVEA.L	int_base(PC),A6
	JMP	-$186(A6)

own_blitter:
	MOVEA.L	lbL0007EA(PC),A6
	JSR	-$1C8(A6)
	JSR	-$E4(A6)
	JSR	-$E4(A6)
	BTST	#6,$DFF002
lbC000674:
	BTST	#6,$DFF002
	BNE.S	lbC000674
	RTS

disown_blitter:
	BTST	#6,$DFF002
lbC000688:
	BTST	#6,$DFF002
	BNE.S	lbC000688
	MOVEA.L	lbL0007EA(PC),A6
	JSR	-$E4(A6)
	JSR	-$E4(A6)
	JSR	-$1CE(A6)
	RTS

swap_zeropage_and_vbr:
	MOVEA.L	zero_copy(PC),A0
	SUBA.L	A1,A1
	MOVE.W	#$FF,D0
lbC0006AE:
	MOVE.L	(A0),D1
	MOVE.L	(A1),(A0)+
	MOVE.L	D1,(A1)+
	DBRA	D0,lbC0006AE
	MOVEA.L	4,A6
	BTST	#0,$129(A6)
	BEQ.S	lbC0006D6
	MOVE.L	old_vbr(PC),D0
	dc.l	$4E7A1801

	MOVE.L	D1,old_vbr
	dc.l	$4E7B0801

lbC0006D6:
	RTS

swap_chipregs:
	LEA	$DFF096,A0
	BTST	#6,-$7C(A0)
	BEQ.S	lbC0006EE
lbC0006E6:
	BTST	#1,-$77(A0)
	BEQ.S	lbC0006E6
lbC0006EE:
	MOVE.W	-$94(A0),D1
	MOVE.W	chip_stores(PC),D0
	BSET	#15,D0
	ANDI.W	#$87FF,D0
	MOVE.W	D0,(A0)
	NOT.W	D0
	ANDI.W	#$87FF,D0
	MOVE.W	D0,(A0)
	MOVE.W	D1,chip_stores
	MOVE.W	-$7A(A0),D1
	MOVE.W	lbW00080C(PC),D0
	BSET	#15,D0
	MOVE.W	D0,4(A0)
	NOT.W	D0
	MOVE.W	D0,4(A0)
	MOVE.W	D1,lbW00080C
	MOVE.W	-$78(A0),D1
	MOVE.W	chip_stores4(PC),D0
	BSET	#15,D0
	MOVE.W	D0,6(A0)
	NOT.W	D0
	MOVE.W	D0,6(A0)
	MOVE.W	D1,chip_stores4
	MOVE.W	-$86(A0),D1
	MOVE.W	lbW000810(PC),D0
	BSET	#15,D0
	MOVE.W	D0,8(A0)
	NOT.W	D0
	MOVE.W	D0,8(A0)
	MOVE.W	D1,lbW000810
	RTS

lbL000764:
	dcb.l	$2,0
	dc.l	$57F0000
	dc.w	0
	dc.l	lbL0007A8
	dcb.w	$8,0
	dc.l	doslibrary
	dc.w	0,1,0,0,0,0,0,0,0,0,0,0,0,0,0
lbL0007A8:
	dcb.l	$2,0
	dc.l	$4000000
	dc.w	0
	dc.b	0
lbB0007B7:
	dc.b	0
aud_task:
	dcb.l	$4,0
	dc.w	0
lbL0007CA:
	dc.l	0
lbL0007CE:
	dc.l	0
lbL0007D2:
	dc.l	0
lbL0007D6:
	dcb.l	$3,0
flags:
	dcb.b	3,0	???
flags3:
	dc.b	0
lbL0007E6:
	dc.l	0
lbL0007EA:
	dc.l	0
int_base:
	dc.l	0
zero_copy:
	dc.l	0
old_vbr:
	dc.l	0
old_taskpri:
	dc.l	0
lbL0007FE:
	dc.l	0
oldsysstack:
	dc.l	0
lbL000806:
	dc.l	0
chip_stores:
	dc.w	0
lbW00080C:
	dc.w	0
chip_stores4:
	dc.w	0
lbW000810:
	dc.w	0
lbB000812:
	dc.b	0
doslibrary:
	dc.b	15
doslibrary0:
	dc.b	'dos.library',0
graphicslibra:
	dc.b	'graphics.library',0
intuitionlibr:
	dc.b	'intuition.library',0
Workbench:
	dc.b	'Workbench',0
audiodevice:
	dc.b	'audio.device',0
cache_alert0:
	dc.b	0
	dc.b	'X',$C
	dc.b	'BACKSTAB LIBRARY ALERT: Unable to allocate a'
	dc.b	'udio channels.',0
	dc.b	$FF
	dc.b	0
	dc.b	'Y',$C
	dc.b	'BACKSTAB LIBRARY ALERT: Unable to allocate a'
	dc.b	'udio channels.',0
	dc.b	$FF
	dc.b	0
	dc.b	$D8
	dc.b	$16
	dc.b	'Take over channels anyway?',0
	dc.b	$FF
	dc.b	0
	dc.b	'\*Left mousebutton',0
	dc.b	$FF
	dc.b	1
	dc.b	$9C
	dc.b	'*Right mousebutton',0
	dc.b	$FF
	dc.b	0
	dc.b	$90
	dc.b	'4YES',0
	dc.b	$FF
	dc.b	1
	dc.b	$D8
	dc.b	'4NO',0,0
cache_alert:
	dc.b	0
	dc.b	'|',$C
	dc.b	'BACKSTAB LIBRARY ALERT: Unable to disable ca'
	dc.b	'ches',0
	dc.b	$FF
	dc.b	0
	dc.b	$85
	dc.b	12
	dc.b	'BACKSTAB LIBRARY ALERT: Unable to disable ca'
	dc.b	'ches.',0
	dc.b	$FF
	dc.b	1
	dc.b	$14
	dc.b	$16
	dc.b	'Run anyway?',0
	dc.b	$FF
	dc.b	0
	dc.b	'\*Left mousebutton',0
	dc.b	$FF
	dc.b	1
	dc.b	$9C
	dc.b	'*Right mousebutton',0
	dc.b	$FF
	dc.b	0
	dc.b	$90
	dc.b	'4YES',0
	dc.b	$FF
	dc.b	1
	dc.b	$D8
	dc.b	'4NO',0,0
backstablibra:
	dc.b	'backstab.library',0
backstablibra0:
	dc.b	'backstab.library 1.0',$D,$A,0
lbW000A0E:
	dc.w	0
	end
