*************************************************************************
* Nome: BLIT3.s								*
*									*
* Autore: Fabrizio Farenga						*
*									*
* Commento: La routine gestisce un BOB a 1 Bitplane in formato RAW che	*
*	    rimbalza per lo schermo.					*
*									*
* Versione: 1.0								*
*									*
* Ultimo aggiornamento: 17-Sep-92 | 14:44:15				*
*									*
* 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		;Altezza del BOB.

;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	#$1F40,d0			;Tenta di allocare la memoria
	move.l	#MEMF_CHIP!MEMF_CLEAR,d1	;necessaria per uno schermo
	CALLEXEC AllocMem			;320x200 a 1 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
	swap	d0		;che abbiamo appena allocato.
	move.w	d0,BPL1H
	move.l	Screen,d0
	move.w	d0,BPL1L

	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,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	#$1F40,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

	dc.l $000FE000,$007FFC00,$01FFFF00,$03FFFF80,$07FFFFC0,$0FFFFFE0
	dc.l $1FFFFFF0,$3FFFFFF8,$3FFFFFF8,$7FFFFFFC,$7FFFFFFC,$7FFFFFFC
	dc.l $FFFFFFFE,$FFFFFFFE,$FFFFFFFE,$FFFFFFFE,$FFFFFFFE,$FFFFFFFE
	dc.l $FFFFFFFE,$7FFFFFFC,$7FFFFFFC,$7FFFFFFC,$3FFFFFF8,$3FFFFFF8
	dc.l $1FFFFFF0,$0FFFFFE0,$07FFFFC0,$03FFFF80,$01FFFF00,$007FFC00
	dc.l $000FE000,$00000000

CopList:
	dc.w $0180,$0000,$0100,$0200,$0182,$0fff
	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 $0108,$0000,$010a,$0000
	dc.w $3101,$fffe,$0100,$1200
	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

