***********************************
*
*
*	VERTICAL BAR SCROLLER
*
*
***********************************

;	AUTO	WS\1024\2\1\

; note: all addresses must be relative referenced (i.e. with PC)

Standalone	; left mouse change bar color, right mouse exit

OldOpenLibrary = -408
CloseLibrary = -414
AllocRaster=	-492
FreeRaster=	-498

; A = AGNUS, D = DENISE, P = PAULA

;DMACON     096      W     A D P   DMA control write (clear or set)
;DMACONR    002      R     A   P   DMA control (and blitter status) read
DMASET=	%1000001110100000 ($8380)
;	 fedcba9876543210

;	f: Set/Clear control bit
;	e: Blitter busy status bit (read only)
;	d: Blotter logic zero status bit (read only)
;	c: X
;	b: X
;	a: Blitter DMA priority (blitter nasty)
;	9: Enable all DMA below
;	8: Bitplane DMA enable
;	7: Copper DMA enable
;	6: Blitter DMA enable
;	5: Sprite DMA enable
;	4: Disk DMA enable
;	3: Audio channel 3 DMA enable
;	2: Audio channel 2 DMA enable
;	1: Audio channel 1 DMA enable
;	0: Audio channel 0 DMA enable
			

;INTENA     09A      W       P    Interrupt enable bits (clear or set bits)
;INTENAR    01C      R       P    Interrupt enable bits (read)
INTENA=	%1100000000100000 ($C020)
;	 fedcba9876543210

;	f: Set/Clear control bit 
;	e: Master interrupt
;	d: External interrupt
;	c: Disk sync register ( DSKSYNC ) matches disk data
;	b: Serial port receive buffer full
;	a: Audio channel 3 block finished
;	9: Audio channel 2 block finished
;	8: Audio channel 1 block finished
;	7: Audio channel 0 block finished
;	6: Blitter finished
;	5: Start of vertical blank
;	4: Copper
;	3: I/O ports and timers
;	2: Reserved for software -initalited interrupt
;	1: Disk block finished
;	0: Serial port transmit buffere empty

scr_width=320
scr_height=256

start:
	IFD	Standalone
		movem.l	d0-d7/a0-a6,-(sp)
	endc
	
	move.l	$4.w,a6
	lea	gfxname(pc),a1
	jsr	oldopenlibrary(a6)		; load graphics library
	move.l	d0,a6
	
	ifd	standalone
	lea	oldcopper(pc),a0
	move.l	$26(a6),(a0)
	endc
	
;---  allocate raster  ---

	move.l	#scr_width,d0		; width
	move.l	#scr_height,d1		; higth
	jsr	allocraster(a6)			; allocate memory for bitplane wxh
	lea	screenptr(pc),a0	
	move.l	d0,(a0)				; write btpl ptr on screenptr
	
;--- clear screen  ---

	move.l	(a0),a0				; point a0 to bitplane address
	move.w	#scr_width/8*scr_height/4-1,d1	; clear 320/8 bytes wide
	moveq	#0,d2				; times 260 bytes high
	
.loopc	
	move.l	d2,(a0)+			; in longwords / 4
	dbf	d1,.loopc
	
;---  set bpl ptrs  ---

	lea.l	bitplanes+2(pc),a0
	moveq	#40,d1
	add.l	d0,d1
	swap	d0					; high word of pointer
	move.w	d0,(a0)				; store high 1
	addq.w	#4,a0
	swap	d0					; low word of pointer
	move.w	d0,(a0)				; store low 1
	
	;sprite pointer

	;move.l	#sprite,d0
	lea.l	sprite(pc),a0
	move.l  a0,d0	
	lea.l	spritepointers(pc),a1
	move.w	d0,6(a1)
	swap	d0
	move.w	d0,2(a1)

	lea	$dff000,a6

	ifd 	standalone

	lea	oldintena(pc),a0
	move.w	$1c(a6),(a0)		; store old intena (intenar)
	lea	olddma(pc),a0
	move.w	$02(a6),(a0)		; store old dmacon (dmaconr)	
	lea	oldinter(pc),a0		
	move.l	$6c.w,(a0)			; store old inter

	endc

;--- disable interrupt

	move.w	#$7fff,$9a(a6)		; clear interrupt enable
	bsr.l	waitvb				; wait for vblank

;--- disable dma

	move.w	#$7fff,$96(a6)		; dma disable	

;--- set interrupt request ---

	lea	inter(pc),a0
	move.l	a0,$6c.w

;--- set interrupt

	move.w	#$7fff,$9c(a6)		; clear request
	move.w	#intena,$9a(a6)		; interrupt enable

;--- set copperlist ---

	lea	copperlist(pc),a0	
	move.l	a0,$80(a6)			; write our copperlist to cop1 loc reg
	moveq	#0,d0
	move.w	d0,$88(a6)			; launch copjmp1
	move.w	d0,$1fc(a6)			; fmode - blp32
	move.w	#$c00,$106(a6)

;--- set dma ---

	move.w	#dmaset,$96(a6)		; set bits of dmacon state

.leftmouse
	btst	#6,$bfe001
	ifnd	standalone
	bne.s	.leftmouse
	
	else
	beq.s	.changecolor
.rightmouse
	btst	#2,$dff016
	bne	.leftmouse
	
	lea	$dff000,a6
	
	move.w	#$7fff,$9a(a6)		; disable interrupts

	bsr.w	waitvb

	move.w	#$7fff,$96(a6)		; disable dma
	
	move.w	olddma(pc),d0
	or.w	#$8000,d0			; set bits of dmacon state
	move.w	d0,$96(a6)			; restore original dmacon

	move.l	oldcopper(pc),$80(a6)	; restore original copperlist
	move.w	d0,$88(a6)			; activate original copperlist

	move.l	oldinter(pc),$6c.w	; restore inter pointer

	move.w	#$7fff,$9c(a6)		; clear requests

	move.w	oldintena(pc),d0
	or.w	#$c000,d0			; set bits of intena state
	move.w	d0,$9a(a6)			; restore original intena

	movem.l (sp)+,d0-d7/a0-a6

	rts
	
	endc
	
.changecolor	
	lea	color01+2(pc),a0
	move.w	(a0),d0				; read $0182 (color1) 
	ror	#4,d0					; change color
	move.w	d0,(a0)				; write color to $0182
	bra.s	.leftmouse

waitvb:
	tst.b	$dff005
	beq.b	waitvb
.loop
	tst.b	$dff005
	bne.s	.loop
	rts

inter:
	movem.l	d0-d7/a0-a6,-(sp)
	
	move.l	screenptr(pc),a0
	lea	linepos(pc),a1
	
	moveq	#0,d1
	move.b	(a1),d1
	move.l	d1,d2				; set vline position to d2

	mulu.w	#40,d1
	add.l	d1,a0				; point to screen according to line pos

	moveq	#10-1,d0
.delline
	move.l	#$00000000,(a0)+
	dbf	d0,.delline				; delete line at screen position
	
	moveq	#10-1,d0
.wrtline
	move.l	#$ffffffff,(a0)+
	dbf	d0,.wrtline				; write line at screen position

	addq	#1,d2
	move.b	d2,(a1)				; update linepos+1
	
	move.w	#$4020,$9c(a6)		; clear interrupt request
	movem.l	(sp)+,d0-d7/a0-a6
	
	rte
	
screenptr:	
	dc.l	0
linepos:	
	dc.b	$ff
	even
oldcopper:
	dc.l	0
oldintena:
	dc.w	0
olddma:
	dc.w	0
oldinter:
	dc.l	0
gfxname:
	dc.b	'graphics.library',0
	even
copperlist:
spritepointers:
	dc.w    $120,$0000,$122,$0000,$124,$0000,$126,$0000,$128,$0000  ; clear sprite pointers
	dc.w    $12a,$0000,$12c,$0000,$12e,$0000,$130,$0000,$132,$0000  ; clear sprite pointers
	dc.w    $134,$0000,$136,$0000,$138,$0000,$13a,$0000,$13c,$0000  ; clear sprite pointers
	dc.w    $13e,$0000

	dc.w	$01a2,$0f00
	dc.w	$01a4,$00f0
	dc.w	$01a6,$0ff0

	dc.l	$01800000
color01:
	dc.l	$01820fff
bitplanes:
	dc.l	$00e00000	; bitplane 1 pointer high bits
	dc.l	$00e20000	; bitplane 1 pointer low bits
	dc.l	$00e40000	; bitplane 2 pointer hight bits
	dc.l	$00e60000	; bitplane 2 pointer low bits
	dc.l	$01001200	; bplcon0 bitplane control register
	dc.l	$01020000	; bplcon1
	dc.l	$01040000	; bplcon2
	dc.l	$01080000	; bitplane modulo (odd planes)
	dc.l	$010a0000	; bitplane modulo (even planes)
	dc.l	$008e2c78	; diwstrt
	dc.l	$00902cc8	; diwstop
	dc.l	$00920038	; ddfstrt
	dc.l	$009400d0	; ddfstop
	dc.l	$fffffffe


SPRITE:			; 13 lines
VSTART:
	dc.b $30	; Vertical position (from $2c a $f2)
HSTART:
	dc.b $90	; Horizontal position (from $40 to $d8)
VSTOP:
	dc.b $3d	; $30+13=$3d	; End vertical position )
	dc.b $00
 dc.w	%0000000000000000,%0000110000110000 
 dc.w	%0000000000000000,%0000011001100000
 dc.w	%0000000000000000,%0000001001000000
 dc.w	%0000000110000000,%0011000110001100 ;BINARY 00=COLOR 0
 dc.w	%0000011111100000,%0110011111100110 ;BINARY 10=COLOR 1 (RED)
 dc.w	%0000011111100000,%1100100110010011 ;BINARY 01=COLOR 2 (GREEN)
 dc.w	%0000110110110000,%1111100110011111 ;BINARY 11=COLOR 3 (YELLOW)
 dc.w	%0000011111100000,%0000011111100000
 dc.w	%0000011111100000,%0001111001111000
 dc.w	%0000001111000000,%0011101111011100
 dc.w	%0000000110000000,%0011000110001100
 dc.w	%0000000000000000,%1111000000001111
 dc.w	%0000000000000000,%1111000000001111
 dc.w	0,0	; two 0 word for ending the sprite

END_PROG

	IF END_PROG-START>512
;	FAIL
	ENDIF

	PRINTT	"PROG SIZE.."
	PRINTV	END_PROG-START
 
	END

>a
Pass 1..
Pass 2..
PROG SIZE..
$0000026E	622 "....
No Errors
>