******************************************************************************
*                                                                            *
*  UD.asm - UpsideDown - A fun (and educational too!) Schwabie               *
*                                                                            *
*  Programmed by Darrin Massena, Mantis Development.                         *
*  No Rights Reserved - Hey everybody, it's FREE!                            *
*                                                                            *
*  To make UD using the Aztec 'C' assembler:                                 *
*    1) as UD.asm                                                            *
*    2) ln -o UD UD.o -lc32                                                  *
*                                                                            *
*  To make UD using the MetaCompost assembler:                               *
*    1) Rewrite first few lines to get a suitable index into the data hunk.  *
*    2) Fix other odd incompatibilities.                                     *
*    3) Wait forever for assembling.                                         *
*    4) Wait forever for linking.                                            *
*    5) Wonder why it doesn't run correctly.                                 *
*    6) Give up and go buy Aztec 'C'.                                        *
*    7) Use the Aztec instructions above.                                    *
*                                                                            *
*  WARNING!  Playing around with the copper-list like this is very much dis- *
*  couraged for SERIOUS programs, but hey, why :-| when you can :-) ?        *
*                                                                            *
*  Revision history :                                                        *
*  ------------------                                                        *
*  06/20/87 (DWM) Just having some innocent fun.                             *
*  06/21/87 (DWM) Aggg!  It's out of control!  RUN, RUN!                     *
*                                                                            *
******************************************************************************

			include	"exec/types.i"
			include	"graphics/gfx.i"
			include	"graphics/gfxbase.i"
			include	"graphics/view.i"
			include	"graphics/copper.i"

			DSEG
SysBase	equ		4

* ===========================================================================
			CSEG
* Define these as public and they'll be pulled in from C32.lib.
			public	_LVOOpenLibrary,_LVOCloseLibrary
			public	_LVOOutput,_LVOWrite

call		MACRO									;macro to call system routines
			jsr	_LVO\1(a6)
			ENDM

* ===========================================================================
			public	UD
UD
* Does anyone know a 'cleaner' way to set the initial A4 data pointer?
*			movea.l	#dummyVar+32766,a4	;special stuff to get my relative A4
			dc.w		%0010100001111100		; <-- doing it the hard way
			dc.l		dummyVar+32766

* If any initializations fail, we'll just abort (cleanly, of course.)
			lea.l		szDOS,a1
			moveq		#0,d0
			move.l	SysBase,a6
			call		OpenLibrary				;open dos.library
			move.l	d0,_DOSBase
			beq		Quit						;failed!

			move.l	d0,a6
			call		Output					;get output filehandle
			move.l	d0,d1						;d1 = out fh
			lea.l		szCredit,a0
			move.l	a0,d2						;d2 = szCredit
			moveq		#-1,d3
99$		addq.l	#1,d3						;loop, counting sz len
			tst.b		(a0)+
			bne		99$
			call		Write						;take the blame

			lea.l		szGfx,a1
			moveq		#0,d0
			move.l	SysBase,a6
			call		OpenLibrary				;open graphics.library
			move.l	d0,_GfxBase
			beq		Quit						;failed? How?

* Will the REAL copper-list please stand up?
			move.l	d0,a0						;a0 = _GfxBase
			move.l	gb_ActiView(a0),a0	;a0 = _GfxBase->ActiView
			move.l	v_ViewPort(a0),a1		;save ptr to first ViewPort
			move.l	v_LOFCprList(a0),a0	;a0 = _GfxBase->ActiView->LOFCprList
			move.l	crl_start(a0),a0		;a0 = ptr to actual copper list in use

* We now have _GfxBase->ActiView->LOFCprList->start (whew!)

* Get a pointer to the first BitMap in the view
			move.l	vp_RasInfo(a1),a1
			move.l	ri_BitMap(a1),a1		;a1 = first BitMap
			move.w	bm_BytesPerRow(a1),d1	;d1 = # of bytes across screen's bm
			move.w	bm_Rows(a1),d2			;d2 = # of rows in screen's BitMap

* Scan through the copper-list until we find the first BPLMOD initialization.
1$			move.l	(a0)+,d0
			swap		d0
			cmp.w		#$0108,d0				;move to BPLMOD1?
			bne		1$							; no, loop until we found it

* Change modulos to step BACK a couple of scanlines instead of forward.
			move.w	d1,d0						;# of bytes for one line across screen
			add.w		d0,d0						; * 2 (have to skip back 2 lines -
			neg.w		d0							; think about it)
			move.w	d0,-2(a0)				;set BPLMOD1 back up 2 lines
			move.w	d0,2(a0)					;set BPLMOD2 back up 2 lines

			subq.w	#1,d2						;bottom line = BytesPerRow * (Rows - 1)
			mulu		d1,d2						;d2 = bottom line

* Since we're going backwards, we have to start at the bottom of each bit-
* plane instead of at the top.
			move.w	6(a0),d0					;first plane hi addr
			swap		d0
			move.w	10(a0),d0				;first plane lo addr
			add.l		d2,d0						;drop to bottom line
			move.w	d0,10(a0)				;put back hi
			swap		d0
			move.w	d0,6(a0)					;put back lo

			move.w	14(a0),d0				;second plane hi addr
			swap		d0
			move.w	18(a0),d0				;second plane lo addr
			add.l		d2,d0						;drop to bottom line
			move.w	d0,18(a0)				;put back hi
			swap		d0
			move.w	d0,14(a0)				;put back lo

* It's time to quit, close up shop and say good-night.
Quit
			move.l	SysBase,a6
			move.l	_DOSBase,d0				;close the dos.library if open
			beq		1$
			move.l	d0,a1
			call		CloseLibrary
1$
			move.l	_GfxBase,d0				;close the graphics.library if open
			beq		2$							; oops, not open
			move.l	d0,a1
			call		CloseLibrary
2$
			rts									;bye!

* ===========================================================================
				DSEG
*  These vars are derived using the Mantis naming conventions.  A brief
*  summary follows:
*
*  p - indicates a pointer
*  n - 'new' structure
*  win,scr,fh - abbreviations for window, screen and filehandle structures
*  co - color 0x0RGB data type
*  sz - null terminated string type
*  rg - range of values (array)
*  b,w,l - byte, word, long data types
*
*  Quiz:  What does prgpfhOpen stand for?
*  .selif nepO fo sretnioP eldnaHeliF fo eGnaR a ot retnioP a :rewsnA

dummyVar											;dummy, used to create my A4
szGfx			dc.b	"graphics.library",0
szDOS			dc.b	"dos.library",0
szCredit		dc.b	"UD - UpsideDown",$a1
				dc.b	" - by Darrin Massena, Mantis Development",$0a
				dc.b	"Press Left-Amiga-N or drag any screen to return to normal.",$0a,0

				even
_GfxBase		dc.l	0
_DOSBase		dc.l	0

* ===========================================================================
				END
