From: breese@monet.imada.ou.dk (Bjoern Reese)
Newsgroups: comp.sys.amiga.programmer
Subject: Hardware bashing demo takes an OS friendly turn.
Date: 7 Jan 93 11:32:38 GMT
Organization: Dept. of Math. & Computer Science, Odense University, Denmark

The recent discussion on hardware bashing made me wonder if I
could adjust one of my demos to be more OS friendly. I took
a demo which I did at the end of 1990 (in fact the last demo
that I released: "Dexion XMas Demo 1990" - well, it was more
like an intro.) My old routines looked like this (a5 points
to my data section in both examples)

;--- Hardware bashing example --------------------------------------
custom	= $DFF000

SystemOff:
	lea	custom,a6
	move.w	intenar(a6),OldIntena(a5)
	move.w	dmaconr(a6),OldDmacon(a5)
	move.w	#$7fff,intena(a6)		;Kill all interrupts & DMA
	move.w	#$7fff,intreq(a6)
	move.w	#$07ff,dmacon(a6)
	move.l	VectorBase(a5),a1		;VectorBase found elsewhere
	move.l	$6c(a1),OldLevel3(a5)		;Save old interrupt pointer
	lea	IntLevel3(pc),a0
	move.l	a0,$6c(a1)			;Install new interrupt
	move.w	#$c020,intena(a6)		;Turn on the interrupts
	move.w	#$83e0,dmacon(a6)		;& DMA that I need
	rts

SystemOn:
	lea	custom,a6
	move.w	#$7fff,intena(a6)
	move.w	#$7fff,intreq(a6)
	move.w	#$07ff,dmacon(a6)
	move.w	OldDmacon(a5),d0
	ori.w	#$8100,d0
	move.w	d0,dmacon(a6)		;Restore DMAs
	move.l	GfxBase(a5),a0
	move.l	38(a0),cop1lc(a6)	;Restore system copperlists
	move.l	50(a0),cop2lc(a6)
	clr.w	copjmp1(a6)
	move.l	VectorBase(a5),a1
	move.l	OldLevel3(a5),$6c(a1)	;Restore interrupt pointer
	move.w	OldIntena(a5),d0
	ori.w	#$c000,d0
	move.w	d0,intena(a6)		;Restore interrupts
	rts
;------------------------------------------------------------------

I substituted them with the routines below (might look a
little messy, because I cut out pieces here, there and
everywhere.)

;--- OS friendly example -------------------------------------------
CALL:	MACRO
	jsr	_LVO\1(a6)
	ENDM

SystemOff:
	move.l	GfxBase(a5),a6
	suba.l	a1,a1
	CALL	LoadView		;Get default view
	CALL	WaitTOF
	CALL	WaitTOF
	CALL	OwnBlitter		;Claim ownership of blitter
	move.l	$0004.w,a6
	CALL	Forbid			;Forbid multitasking
	moveq.l	#5,d0			;VERTB
	lea	VBlankServer(pc),a1
	CALL	AddIntServer		;Add my interrupt to system list
	rts

SystemOn:
	move.l	$0004.w,a6
	moveq.l	#5,d0
	lea	VBlankServer(pc),a1
	CALL	RemIntServer		;Remove my interrupt
	CALL	Permit			;Permit multitasking
	move.l	GfxBase(a5),a6
	CALL	DisownBlitter		;Give blitter back
	move.l	MyView(a5),a1
	CALL	LoadView		;Load original view
	rts

IntLevel3:
	movem.l	d0-d7/a0-a6,-(sp)
	...
	movem.l	(sp)+,d0-d7/a0-a6
	rts				;Not rte!!!

VBlankServer:
	dc.l	0,0		;ln_Succ,ln_Pred
	dc.b	2,0		;ln_Type,ln_Pri
	dc.l	IntName		;ln_Name
	dc.l	0,IntLevel3	;is_Data,is_Code

IntName:dc.b	"Dexion IntLevel3",0
	EVEN
;------------------------------------------------------------------

where MyView(a5) is filled in immediately after graphics.library
have been opened:

	...
	move.l	GfxBase(a5),a1
	move.l	gb_ActiView(a1),MyView(a5)
	...

And guess what. It works without any problems!

The original version would crash on M68010+ CPUs, because I
failed to realize that MOVEC VBR,A0 , which I used to obtain
the vectorbase, was a priviledged instruction :( Not know I
don't need it anymore.

I had to give up using WaitBlit() in preference of testing the
BBUSY bit in the dmaconr hardware register by myself. Using
WaitBlit() increased the execution time about 1/5 of a frame
(which I could afford), but as I depended on the preservation
of all data registers and most address registers I had to dump
the scratch registers on the stack, which increased execution
time about 1/2 frame (and that I couldn't afford).

Just to give you an idea of what I was doing, the demo consisted
of a scroller which rotated and twisted at the same time (rotation
on the screen, rotation around itself, and a sine.) I used 16 bit
long (short :) lines with the blitter mask containing the font data
to draw the scroller. _240 blitter lines_ were needed. I used
Bresenhams line algorithm to calculate the rotating coordinates
of the scroller. I also used a sprite multiplexer with 16 sprites
(using shellsort.) Oh yes, and another full-screen scroller, which
used ring-buffer, so it didn't really take much time.


I am posting these code fragments in the hope that someone could
find them useful (the OS friendly fragments, _not_ the bashing-only
fragments.) I would urge hardware bashers to read 'howtocode2.txt'
which can be fould on any aminet site (/pub/aminet/text/docs/)

--

Bjoern Reese                   |     Email: breese@imada.ou.dk
Odense University, Denmark     |     Voice: +45 65 932 182 (private)