*************************************************************************
* Nome: BLIT4.s								*
*									*
* Autore: Fabrizio Farenga						*
*									*
* Commento: La routine gestisce il rimbalzo per lo schermo di un BOB	*
*	    a 2 BitPlane in formato BLITRAW.				*
*									*
* Versione: 1.0								*
*									*
* Ultimo aggiornamento: 17-Sep-92 | 14:47:18				*
*									*
* Bugs: Nessuno conosciuto						*
*									*
*************************************************************************


CALLEXEC:	MACRO			;Macro di chiamata per le routine
	MOVE.L	[_SysBase].W,A6		;dell'Exec.
	JSR	_LVO\1(A6)
	ENDM


	SECTION BlitCode,Code

WIDTHS EQU 4		;Larghezza dello schermo in cui e' depositato il BOB
WIDTHD EQU 40		;Larghezza dello schermo in cui va' stampato il BOB
DIMX EQU 32+16		;Larghezza del BOB (+16 per lo shifter)
DIMY EQU 32*2		;Altezza del BOB (*2 perche' sono 2 bitplane "fusi").

;TUTTE LE MISURE SOVRASTANTI SONO ESPRESSE IN BYTE (PIXEL/8)

SPEED EQU 4			;Velocita' di movimento (1,2,4,8).
BOBX EQU SPEED			;Coordinata X di partenza del BOB.
BOBY EQU SPEED			;Coordinata Y di partenza del BOB.

_SysBase=4			;EXECBASE.

_LVODisable	=	-120 	;Routine dell'EXEC utilizzate dal programma.
_LVOEnable	=	-126 
_LVOAllocMem	=	-198 
_LVOFreeMem	=	-210 
_LVOOpenLibrary	=	-552 

MEMF_CHIP:	EQU 2		;Flag di definizione del tipo di Memoria.
MEMF_CLEAR:	EQU $10000

DMACONR:	EQU   $DFF002	;Registri dei Chip Custom utilizzati dal
VHPOSR:		EQU   $DFF006	;programma.
BLTCON0:	EQU   $DFF040
BLTCON1:	EQU   $DFF042
BLTAFWM:	EQU   $DFF044
BLTALWM:	EQU   $DFF046
BLTAPT:		EQU   $DFF050
BLTDPT:		EQU   $DFF054
BLTSIZE:	EQU   $DFF058
BLTAMOD:	EQU   $DFF064
BLTDMOD:	EQU   $DFF066
COP1LC:		EQU   $DFF080
DMACON:		EQU   $DFF096

CIAAPRA:	EQU   $BFE001	;Registro del CIAA utilizzato dal programma.

Start:
	lea	GFXName,a1	;Apre la 'graphics.library'.
	moveq	#0,d0
	CALLEXEC OpenLibrary
	move.l	d0,GFXBase

	move.l	d0,a0		;Memorizza in OLDCOP l'indirizzo della
	move.l	$26(a0),OldCop	;Copperlist del Sistema Operativo.

	move.l	#$3E80,d0			;Tenta di allocare la memoria
	move.l	#MEMF_CHIP!MEMF_CLEAR,d1	;necessaria per uno schermo
	CALLEXEC AllocMem			;320x200 a 2 bitplane.
	move.l	d0,Screen
	beq	ErrorExit	;Se non c'e' abbastanza memoria esci.

	CALLEXEC Disable	;Disabilita il Sistema Operativo.

	move.l	Screen,d0	;Punta la nostra CopperList allo schermo
	move.w	d0,BPL1L	;che abbiamo appena allocato.
	swap	d0
	move.w	d0,BPL1H

	move.l	Screen,d0	;Punta la nostra CopperList allo schermo
	add.l	#WIDTHD,d0
	move.w	d0,BPL2L	;che abbiamo appena allocato.
	swap	d0
	move.w	d0,BPL2H

	move.w	#$0020,DMACON	;Spegne gli Sprite.
	move.l	#CopList,COP1LC	;Attiva la nostra CopperList.
	bra	SkipClear	;Evita la prima pulizia del fondo (lo schermo
				;e' gia pulito).

BlitLoop:
	jsr	WaitBlit	;Attendi che il Blitter sia libero

; La routine che segue ripulisce la zona di memoria dove si era stampato
; il BOB il quadro video precedente. Essa riutilizza tutti i valori gia'
; impostati dalla stampa del BOB.

	and.w	#%1111011100000000,d0	;Disattiva il canale A e i mintermi.
	move.w	d0,BLTCON0
	move.w	#0,BLTCON1
	move.l	d1,BLTDPT			;Punta il Canale D.
	move.w	#WIDTHD-(DIMX/8),BLTDMOD	;Modulo del Canale D
	move.w	#(DIMY*64)!(DIMX/16),BLTSIZE	;Dimensioni del Blitter
SkipClear:

	moveq	#0,d1		;Calcola il valore da aggiungere alla
	move.w	CoordX,d1	;coordinata 0,0 dello schermo per stampare
	lsr.w	#3,d1		;il BOB alle coordinate CoordX e CoordY
	move.w	CoordY,d0
	mulu	#40*2,d0
	add.w	d0,d1
	add.l	Screen,d1

	move.w	CoordX,d0	;Calcola lo shifter del Canale A
	and.w	#15,d0
	ror.w	#4,d0
	ori.w	#%0000100111110000,d0
;		  |
;		  |
;Questi 16 bit rappresentano il valore che verra' immesso il BLTCON0 ed
;e' cosi' ripartito a cominciare da destra:
;Bit 00-07 -> Minitermi=11110000 (copia del Canale A)
;Bit 08-11 -> Attivazione canali (A--D)
;Bit 12-15 -> Shifter (viene impostato dalla routine precedente)

	jsr	WaitBlit	;Attende che il Blitter sia libero.

	move.w	d0,BLTCON0	;Setta il BLTCON0.
	move.w	#0,BLTCON1	;Azzera il BLTCON1 (modo linea spento).
	move.w	#$FFFF,BLTAFWM	;Mascheratura delle Word di sinistra tutta a 1.
				;In questo modo sono trasferite integralmente.
	move.w	#0,BLTALWM	;Mascheratura delle Word di destra tutta a 0.
				;In questo modo e' del tutto "tagliata".
	move.l	#Bob,BLTAPT	;Punta il Canale A al Bob.
	move.l	d1,BLTDPT	;Imposta il Canale D secondo i valori calcolati
				;precedentemente.
	move.w	#WIDTHS-(DIMX/8),BLTAMOD		;Modulo del Canale A
	move.w	#WIDTHD-(DIMX/8),BLTDMOD		;Modulo del Canale D
	move.w	#(DIMY*64)!(DIMX/16),BLTSIZE		;Dimensioni del Blitter
;		 |
;	         |
;L'altezza e' impostata secondo il valore di DIMY, mentre la larghezza e'
;basata sul valore di DIMX.


WaitLoop:
	btst	#6,CIAAPRA	;Se il tasto sinistro del Mouse e' premuto
	beq	Exit		;esce.
	cmp.b	#$fF,VHPOSR	;Attende che il pennello elettronico raggiunga
	bne	WaitLoop	;l'ultima linea del quadro 320x200.

;***********************************

	move.w	XDir,d2		;Routine di calcolo del rimbalzo.
	add.w	d2,CoordX
	beq	ChangeX
	cmp.w	#288,CoordX
	bne	NoChangeX
ChangeX:
	exg	d2,d3
	move.w	#0,XDir
	sub.w	d3,XDir
NoChangeX:

	move.w	YDir,d2
	add.w	d2,CoordY
	beq	ChangeY
	cmp.w	#160,CoordY
	bne	NoChangeY
ChangeY:
	exg	d2,d3
	move.w	#0,YDir
	sub.w	d3,YDir
NoChangeY:

;***********************************

	bra	BlitLoop	;Ristampa il BOB alle coordinate appena
				;aggiornate.

Exit:				;Routine di uscita.
	move.l	OldCop,COP1LC	;RImette a posto la CopperList del S.O.
	move.w	#$8020,DMACON	;Riattiva gli sprite.
	CALLEXEC Enable		;Riattiva il Sistema Operativo.
	jsr	FreeMem		;Libera la memoria allocata.
ErrorExit:
	rts
	
FreeMem:			;Routine che libera la memoria allocata.
	move.l	Screen,a1
	move.l	#$3E80,d0
	CALLEXEC FreeMem
	rts

WaitBlit:			;Routine che attende che il Blitter sia libero
	btst	#14,DMACONR	;Fa un controllo fittizio per evitare il BUG di
WaitBlitLoop:			;alcuni vecchi AGNUS
	btst	#14,DMACONR	;Esegue il vero controllo.
	bne	WaitBlitLoop
	rts

;*************************

	SECTION BlitChipData,DATA_C

Bob:	;Dati grafici del BOB (2 BitPlane in formato RAWBLIT

	dc.l $00000000,$000FE000,$000FE000,$00701C00,$007FFC00,$01800300
	dc.l $01FFFF00,$02000080,$03FFFF80,$04000040,$07FFFFC0,$08000020
	dc.l $0FFFFFE0,$10000010,$1FFFFFF0,$20000008,$1FFFFFF0,$20701C08
	dc.l $3FFFFFF8,$40F83E04,$3FFFFFF8,$40F83E04,$3FFFFFF8,$40F83E04
	dc.l $7FFFFFFC,$80701C02,$7FFFFFFC,$80000002,$7FFFFFFC,$80000002
	dc.l $7FFFFFFC,$80000002,$7FFFFFFC,$82000082,$7FFFFFFC,$82000082
	dc.l $7FFFFFFC,$83000182,$3FFFFFF8,$43000184,$3FFFFFF8,$41800304
	dc.l $3FFFFFF8,$41800304,$1FFFFFF0,$20E00E08,$1FFFFFF0,$20F83E08
	dc.l $0FFFFFE0,$107FFC10,$07FFFFC0,$081FF020,$03FFFF80,$0407C040
	dc.l $01FFFF00,$02000080,$007FFC00,$01800300,$000FE000,$00701C00
	dc.l $00000000,$000FE000,$00000000,$00000000

CopList:
	dc.w $0180,$0000,$0100,$0200,$0182,$0dd0,$0184,$00f0,$0186,$000f
	dc.w $008E,$2C81,$0090,$F4C1,$0092,$0038,$0094,$00D0
	dc.w $3001,$fffe,$00e0
BPL1H:
	dc.w $0000,$00e2
BPL1L:
	dc.w $0000
	dc.w $00e4
BPL2H:
	dc.w $0000,$00e6
BPL2L:
	dc.w $0000
	dc.w $0108,$0028,$010a,$0028	;Modulo del Copper posto a $28
	dc.w $3101,$fffe,$0100,$2200
	dc.w $ff01,$fffe,$0100,$0200
	dc.w $ffff,$fffe



	SECTION BlitData,DATA

Screen:		dc.l 0		;Puntatore alla memoria per lo schermo
GFXBase:	dc.l 0		;Puntatore alla Base della 'graphics.library'
OldCop:		dc.l 0		;Puntatore alla Copperlist del S.O.
CoordX:		dc.w BOBX	;Coordinata X corrente del BOB
CoordY:		dc.w BOBY	;Coordinata Y corrente del BOB
XDir:		dc.w SPEED	;Incremento corrente della coordinata X
YDir:		dc.w SPEED	;Incremento corrente della coordinata Y
GFXName:	dc.b 'graphics.library',0	;Nome della libreria

		CNOP 0,2

