; $$TABS=12

	exeobj

	include	"strucdef.asm"
	include	"lvo.asm"
filesize	equ	512*1024

;
; SlowDown.Asm  - Measure I/O overhead of Disk device
; Creates a 256K temporary file in the current directory.
; Run a compute-bound benchmark with and without disk I/O at the same time.
;
	move.l	4,a6
	move.l	#filesize,d0
	moveq	#0,d1
	jsr	_LVOAllocMem(a6)
	move.l	d0,the_mem
	lea	intuiname(pc),a1
	moveq	#0,d0
	jsr	_LVOOpenLibrary(a6)
	move.l	d0,intuibase
	moveq	#-1,d0
	jsr	_LVOAllocSignal(a6)
	move	d0,the_sig
	sub.l	a1,a1
	jsr	_LVOFindTask(a6)
	move.l	d0,the_task
	bsr	add_the_task
	moveq	#1,d0
	move	the_sig(pc),d1
	lsl.l	d1,d0
	jsr	_LVOWait(a6)
	movem.l	secs1(pc),d0/d1
	movem.l	d0/d1,fast_secs
	lea	dosname(pc),a1
	moveq	#0,d0
	jsr	_LVOOpenLibrary(a6)
	move.l	d0,a6
	move.l	#my_fname,d1
	move.l	#mode_newfile,d2
	jsr	_LVOOpen(a6)
	move.l	d0,d7
	move.l	d7,d1
	move.l	the_mem(pc),d2
	move.l	#filesize,d3
	jsr	_LVOWrite(a6)
	move.l	d7,d1
	moveq	#0,d2
	moveq	#-1,d3
	jsr	_LVOSeek(a6)	; rewind file
	move.l	a6,a5
	bsr	add_the_task
time_loop:	move.l	a5,a6
	move.l	d7,d1
	move.l	the_mem(pc),d2
	move.l	#filesize,d3
	jsr	_LVORead(a6)
	move.l	d7,d1
	moveq	#0,d2
	moveq	#-1,d3
	jsr	_LVOSeek(a6)	; rewind file
	move.l	4,a6
	moveq	#0,d0
	moveq	#0,d1
	jsr	_LVOSetSignal(a6)
	move	the_sig(pc),d1
	btst	d1,d0
	beq.s	time_loop
	move.l	d7,d1
	move.l	a5,a6
	jsr	_LVOClose(a6)
	move.l	#my_fname,d1
	jsr	_LVODeleteFile(a6)
got_time:	move.l	fast_secs(pc),d0
	sub.l	secs1(pc),d0
	muls	#1000,d0
	move.l	secs1(pc),d1
	divs	d1,d0
	add.l	#1000,d0
; time now in d0
	ext.l	d0
	divu	#1000,d0
	tst	d0
	beq.s	no_hdig
	add.b	#'0',d0
	move.b	d0,p1-1
no_hdig:	clr	d0
	swap	d0
	divu	#100,d0
	add.b	#'0',d0
	move.b	d0,p1
	clr	d0
	swap	d0
	divu	#10,d0
	add.b	#'0',d0
	move.b	d0,p1+1
	swap	d0
	add.b	#'0',d0
	move.b	d0,p1+3
	move.l	a5,a6
	jsr	_LVOOutput(a6)
	move.l	d0,d1
	move.l	#message,d2
	move.l	#end_message-message,d3
	jsr	_LVOWrite(a6)
	move.l	the_mem(pc),a1
	move.l	#filesize,d0
	move.l	4,a6
	jsr	_LVOFreeMem(a6)
	rts
	
add_the_task:
	move.l	4,a6
	lea	my_task(pc),a1
	clr.b	ln_Pri(a1)
	move.b	#NT_TASK,ln_type(a1)
	move.l	#end_stack,TC_SPREG(a1)
	move.l	#end_stack,TC_SPUPPER(a1)
	move.l	#start_stack,TC_SPLOWER(a1)
	lea	TC_MEMENTRY(a1),a0
	NEWLIST	a0
	lea	take_some_time(pc),a2
	sub.l	a3,a3
	jmp	_LVOAddTask(a6)


take_some_time:
; matrix multiply and code a bunch of points.
; this should not be taken as an example of efficient 3D code; it's not!
; there may be bugs in it.. It's not meant to generate a useful result, just
; to take time.

ent1:	move.l	intuibase(pc),a6
	lea	secs(pc),a0
	lea	micros(pc),a1
	jsr	_LVOCurrentTime(a6)
	move.l	#131072,counter
points_loop	movem	pnt(pc),d0/d1/d2
	lea	m1(pc),a0
	movem	(a0)+,d3/d4/d5
	muls	d0,d3
	muls	d1,d4
	muls	d2,d5
	add.l	d4,d3
	add.l	d5,d3
	add.l	d3,d3
	swap	d3
	movem	(a0)+,d4/d5/d6
	muls	d0,d4
	muls	d1,d5
	muls	d2,d6
	add.l	d5,d4
	add.l	d6,d4
	add.l	d4,d4
	swap	d4
	movem	(a0)+,d5/d6/d7
	muls	d0,d5
	muls	d1,d6
	muls	d2,d7
	add.l	d6,d5
	add.l	d7,d5
	add.l	d5,d5
	swap	d5
	movem	d3/d4/d5,rslt
	move	d5,d0
	and	#$7fff,d0
	cmp	d3,d5
	ble.s	no_1
	addq	#1,d0
no_1:	cmp	d4,d5
	ble.s	no_2
	addq	#2,d0
no_2:	neg	d5
	cmp	d4,d5
	bge.s	no_3
	addq	#4,d0
no_3:	cmp	d3,d5
	bge.s	no_4
	addq	#8,d0
no_4:	subq.l	#1,counter
	bne.s	points_loop
	lea	secs1(pc),a0
	lea	micros1(pc),a1
	jsr	_LVOCurrentTime(a6)
	movem.l	secs(pc),d0/d1
	sub.l	d1,micros1
	bpl.s	no_adj
	add.l	#1000000,micros1
	addq.l	#1,d1
no_adj:	sub.l	d0,secs1
	moveq	#1,d0
	move	the_sig(pc),d1
	lsl.l	d1,d0
	move.l	the_task(pc),a1
	move.l	4,a6
	jsr	_LVOSignal(a6)
	rts


	
my_task	dc.l	0
	dc.l	0
	dc.b	NT_TASK
	dc.b	0
	dc.l	my_task_name
	dc.w	0
	dc.w	0
	dc.l	0,0,0,0
	dc.l	0
	dc.l	0,0,0,0
	dc.l	end_stack
	dc.l	start_stack,end_stack
	dc.l	0,0
	dc.l	0,0,0,0,0

intuibase	dc.l	0
start_stack	ds.l	30
end_stack:
the_sig	dc.w	0
the_task	dc.l	0
m1	dc.w	$5555,$aaaa,$1234,$4321,$1111,$7777,$0987,$6789,$3141
pnt	dc.w	$6543,$3214,$542
counter	dc.l	0
rslt	dc.w	0,0,0
secs	dc.l	0
micros	dc.l	0
secs1	dc.l	0
micros1	dc.l	0
fast_secs	dc.l	0,0
the_mem	dc.l	0
intuiname	dc.b	'intuition.library',0
dosname	dc.b	'dos.library',0
my_task_name:
	dc.b	'SlowDown Task',0
my_fname	dc.b	'slowdown.temp.file',0
message:	dc.b	'Efficiency=  '
p1	dc.b	'xx.x%',10
end_message:

	end
