		; *********************************************
		; ** © Offworld production                  ***
		; **----------------------------------------***
		; ** Coding by Zany, graphics by Open Eyes  ***
		; *********************************************


		; Offsets for allocated memory ------------------------------

HowMuch         EQU   20000	; How much to allocate memory

BPStart         EQU   $0000	; start of the first bit plane

		; Offsets: miscellaneous

BPHowMany       EQU   1-1	; how many bit planes used
BPSize          EQU   $2500	; size of bit plane


		; Offsets: exec.lib

OpenLib         EQU   -$228
CloseLib        EQU   -$19e
AllocMem        EQU   -$0C6
FreeMem         EQU   -$0D2
Forbid          EQU   -$084
Permit          EQU   -$08A

		; Offsets: intuition.lib		

DispAlert       EQU   -$05a
		
		; Offsets for custom chips

dmaconr         EQU   $002
vposr           EQU   $004
vhposr          EQU   $006
joy0dat         EQU   $00A
joy1dat         EQU   $00C
intenar         EQU   $01C
intreqr         EQU   $01E
copcon          EQU   $02E
bltcon0         EQU   $040
bltcon1         EQU   $042
bltafwm         EQU   $044
bltalwm         EQU   $046
bltcpt          EQU   $048
bltbpt          EQU   $04C
bltapt          EQU   $050
bltdpt          EQU   $054
bltsize         EQU   $058
bltcmod         EQU   $060
bltbmod         EQU   $062
bltamod         EQU   $064
bltdmod         EQU   $066
bltcdat         EQU   $070
bltbdat         EQU   $072
bltadat         EQU   $074
cop1lc          EQU   $080
cop2lc          EQU   $084
copjmp1         EQU   $088
copjmp2         EQU   $08A
copins          EQU   $08C
diwstrt         EQU   $08E
diwstop         EQU   $090
ddfstrt         EQU   $092
ddfstop         EQU   $094
dmacon          EQU   $096
intena          EQU   $09A
intreq          EQU   $09C
bplpt           EQU   $0E0
bplcon0         EQU   $100
bplcon1         EQU   $102
bplcon2         EQU   $104
bpl1mod         EQU   $108
bpl2mod         EQU   $10A
sprpt           EQU   $120
spr             EQU   $140
color           EQU   $180


		; Macros starts here ----------------------------------------

Push:		macro				; Registers to stack
		movem.l d2-d7/a2-a6,-(sp)
		endm

Pull:		macro				; Registers from stack
		movem.l (sp)+,d2-d7/a2-a6
		endm

StopDrive:	macro				; Stops motor of the drive
		move.b	#$fd,$bfd100
		nop
		nop
		move.b	#$f5,$bfd100
		endm

CWait: 	 	macro				; Copper wait
  		dc.b 	\2			
  		dc.b 	\1*2+1
  		dc.w 	$fffe
  		endm

CMove:		macro				; Copper move 
  		dc.w 	\1,\2
  		endm

CStop:	 	macro				; Stops copper
  		dc.w 	$ffff,$fffe
  		endm


		; Code starts here ------------------------------------------

		Push
	
		move.l	$04,a6

		move.l	#HowMuch,d0		
		move.l	#$10002,d1		; allocate chip and clear
		jsr	AllocMem(a6)
		move.l	d0,MemBase
		beq.l	NoMem			; didn't get memory

		jsr	Forbid(a6)		; no multitasking

		move.l	$80,OldTrap0
		move.l	#Start,$80
		trap	#0
		move.l	OldTrap0,$80

		move.l	$4,a6			; free allocated memory
		move.l	#HowMuch,d0
		move.l	MemBase(pc),a1			
		jsr	FreeMem(a6)
	
DoPermit	jsr	Permit(a6)		; enable multitasking

		Pull
		moveq	#0,d0
		rts


		; here the code starts --------------------------------------


Start		btst	#14,DMAConr+$dff000	; wait blitter
		bne.s	Start

		bsr	FinishCopList


		move.l	#ScrollTxt,ScrollTxtPt

		lea	$dff000,a6
		bsr	SetCopIntDMA		


		; All settings done


TstMouse	btst	#$06,$bfe001		; test is m-button pushed
		bne.s	TstMouse

EndBLTWait	btst	#14,DMAConr+$dff000	; wait blitter
		bne.s	EndBLTWait

		lea	$dff000,a6
		bsr	ResetAll

	
		rte				; back from trap	


		; Some finishing stuff to copper list -----------------------

FinishCopList	lea	BitPlanes,a0
		move.l	MemBase,d0
		add.l	#BPStart,d0
		move.l	d0,BitPlaneBase
		move.l	#BPHowMany,d1

BPSetLoop	move.w	d0,$6(a0)
		swap	d0
		move.w	d0,$2(a0)
		swap	d0
		add.l	#BPSize,d0
		add.l	#$08,a0
		dbf	d1,BPSetLoop

		lea	Sprites,a0	
		move.l	#SprImage,d0			; set sprite pointers
		move.l	#$07,d1

SprSetLoop	move.w	d0,6(a0)
		swap	d0
		move.w	d0,2(a0)
		swap	d0
		add.l	#$08,a0
		dbf	d1,SprSetLoop
		

		rts

		; Set and reset copperlist, interrupts and DMA - ------------

SetCopIntDMA	move.w	IntEnar(a6),d0			; get old interrupt
		and.w	#$4fff,d0			; values
		move.w	d0,OldIntEna

		move.w	DMAConr(a6),d0			; get old DMA control
		and.w	#$7ff,d0			; values
		move.w	d0,OldDMACon

		move.w	#$7fff,DMACon(a6)		; registers
		move.w	#$7fff,IntEna(a6)		; clear both

		move.l	#OwnCopper,Cop2lc(a6)		; own copperlist
		move.w	CopJmp2(a6),d0
		move.w	#$83e0,DmaCon(a6)		; enable DMA

		move.l	$6c,OldInt
		move.l	#Interrupt,$6c			; own interrupt
		move.w	#$c020,IntEna(a6)		; enable interrupts

	
		rts


ResetAll	move.w	#$7fff,IntEna(a6)		; clear both
		move.w	#$7fff,DMACon(a6)		; registers

		move.l	OldInt,$6c			; old interrupt back
	
		move.w	CopJmp1(a6),d0			; old copperlist

		move.w	OldIntEna,d0			; old interrupt
		or.w	#$8000,d0			; enable
		move.w	d0,IntEna(a6)

		move.w	OldDMACon,d0			; old DMA control
		or.w	#$8000,d0
		move.w	d0,DmaCon(a6)	

		rts

		; Interrupt code here ---------------------------------------
	
Interrupt	move.w	sr,-(sp)
		Push

		lea	$dff000,a6

		move.w	#$0020,IntReq(a6)		; reset
		move.w	CopJmp2(a6),d0

		lea	$dff000,a6
		bsr	Scroll

		Pull
		move.w	(sp)+,sr
		rte

		; 8x8 Scroller ----------------------------------------------
		; 
		; a6 must be $dff000

ScrollWidht     EQU   $2c
ScrollHeight    EQU   $08

		; in this scroller speed can only be 1, 2, 4 or 8

ScrollSpeed     EQU   $02

Scroll		move.l	BitPlaneBase,a0		; address of source bitplane
		add.l	#ScrollWidht-2,a0
		move.l	a0,a1
		addq.l	#$02,a0
	
ScrollBltWait	btst	#$06,DMAConr(a6)
		bne	ScrollBltWait

		move.l	#[[0-ScrollSpeed]*$10000000]+$9f00000,BltCon0(a6)
		move.l	#$0fffffff,BltAfwm(a6)
		move.l	#$00000000,BltAMod(a6)	; move scroll-text two pixels
		move.l	a0,BltAPt(a6)		; left
		move.l	a1,BltDPt(a6)
		move.w	#[ScrollHeight*64]+[ScrollWidht/2],BltSize(a6)

		sub.b	#ScrollSpeed,ScrXPt	; have we scrolled whole
		bcc	ScrollNoNeg		; char left

		move.b	#$07,ScrXPt		

		moveq	#$00,d0
		move.l	ScrollTxtPt,a0

ScrollGetChar	move.b	(a0)+,d0		; get scroll text
		bne	ScrollNoWrap
		move.l	#ScrollTxt,a0
		move.l	a0,ScrollTxtPt
		bra	ScrollGetChar

ScrollNoWrap	addq.l	#$01,ScrollTxtPt
		sub.b	#$20,d0
		
		lea	ScrollFont,a0
		add.l	d0,a0

		add.l	#ScrollWidht-1,a1

		move.b	#$07,d0
		
ScrollPlotChar	move.b	(a0),(a1)		; plot new char to screen
		add.l	#$50,a0
		add.l	#ScrollWidht,a1
		dbf	d0,ScrollPlotChar

ScrollNoNeg	rts

		; if no free memory, then display alert ---------------------

NoMem		moveq	#0,d0
		lea	IntuiName,a1
		move.l	$04,a6
		jsr	OpenLib(a6)
		move.l	d0,IntuiBase
		beq	DoPermit

		exg	a6,d0
		moveq.l	#$00,d0
		move.l	#$30,d1
		lea	AlertText(pc),a0
		jsr	DispAlert(a6)

		move.l	IntuiBase,a1
		move.l	$04,a6
		jsr	CloseLib(a6)

		jmp	DoPermit
	

	; -----------------------------------------------------------

IntuiName	dc.b	'intuition.library',$00	

AlertText	dc.w	$0014
		dc.b	$10
		dc.b	'NOT enough FREE memory for demo! ',$00
		dc.b	$01
		dc.w	$0014
		dc.b	$1a
		dc.b	'Please, reset your computer and load this '
		dc.b	'demo again.',$00
		dc.b	$01
		dc.w	$0014
		dc.b	$24
		dc.b	'Signed: Zany / Offworld',$00
		dc.b	$00

ScrXPt		dc.b	$00

ScrollTxt	dc.b	"      JOOPS...          THIS SCROLLER IS STANDARD "
		dc.b	"8X8 SCROLLER WHICH WAS 'CODED' BY ZANY/OFFWORLD.  "
		dc.b	"           THIS STANDARD FONT WAS ALSO DONE BY ME "
		dc.b	"(ZANY)                                            "
		dc.b	$00
	
		even

IntuiBase	dc.l	$00000000

OldIrq		dc.l	$00000000

MemBase		dc.l	$00000000

BitPlaneBase	blk.l	BPHowMany+1,$00
	
OldTrap0	dc.l	$00000000

OldInt		dc.l	$00000000

ScrollTxtPt	dc.l	$00000000

OldDMACon	dc.w	$0000

OldIntEna	dc.w	$0000


	; Here datas which must be in CHIP-memory ---------------------------

SprY            EQU   $26
SprX            EQU   $d0

SprImage	dc.w	SprY*$100+SprX,[SprY+1]*$100+6
		dc.l	$00000000

	; copperlist here ---------------------------------------------------

OwnCopper

BitPlanes
		CMove	BPLPt,  $0000			; BP 1 pointer
		CMove	BPLPt+2,$0000

		CMove	BPLCon0,%0001000000000000 	; control bits
		CMove	BPLCon1,%0000000000000000	; horizontal scroll
		CMove	BPLCon2,$0024	
		CMove	BPL1Mod,$0004
		CMove	BPL2Mod,$0004
		CMove	DDFStrt,$0038			; Disp. data fetch
		CMove	DDFStop,$00d0			; Disp. data fetch
		CMove	DiWStrt,$2c81			; Disp. window start
		CMove	DiWStop,$2cc1			; Disp. window stop
Sprites
		CMove	Sprpt,$0000
		CMove	Sprpt+2,$0000
		CMove	Sprpt+4,$0000
		CMove	Sprpt+6,$0000
		CMove	Sprpt+8,$0000
		CMove	Sprpt+10,$0000
		CMove	Sprpt+12,$0000
		CMove	Sprpt+14,$0000
		CMove	Sprpt+16,$0000
		CMove	Sprpt+18,$0000
		CMove	Sprpt+20,$0000
		CMove	Sprpt+22,$0000
		CMove	Sprpt+24,$0000
		CMove	Sprpt+26,$0000
		CMove	Sprpt+28,$0000
		CMove	Sprpt+30,$0000

		CMove	Color,$0000
		CMove	Color+2,$0fff
		CMove	Color+34,$0444
		CMove	Color+36,$0777
		CMove	Color+38,$0aaa
	
		CStop

ScrollFont	incbin	"df0:graphics/font.8x8"

