*************************************************************************
* Nome: Lpen.s								*
*									*
* Autore: Fabrizio Farenga						*
*									*
* Commento: Gestisce il movimento di uno sprite tramite una Penna	*
*	    Ottica collegata alla porta 2.				*
*									*
* Versione: 1.1								*
*									*
* Ultimo aggiornamento: 17-Oct-93 | 20:06				*
*									*
* Bugs: Nessuno conosciuto						*
*									*
*************************************************************************

		SECTION LPEN,CODE_C	;Ordina all'assemblatore di allocare
					;tutto nella memoria Chip.

HEIGHT		EQU 16		;Altezza (in pixel) dello sprite.

PALSYNC:	EQU $0020	;Frequenza video per la modalita' PAL.
NTSCSYNC:	EQU $0000	;Frequenza video per la modalita' NTSC.

;Registri dei Chip Custom utilizzati

DMACONR		EQU $DFF002
VPOSR		EQU $DFF004
VHPOSR		EQU $DFF006
INTENAR		EQU $DFF01C
INTREQR		EQU $DFF01E
COP1LC		EQU $DFF080
COP2LC		EQU $DFF084
COPJMP1		EQU $DFF088
COPJMP2		EQU $DFF08A
DMACON		EQU $DFF096
INTENA		EQU $DFF09A
JOY0DAT:	EQU $DFF00A
JOY1DAT:	EQU $DFF00C
COLOR00:	EQU $DFF180
COLOR01:	EQU $DFF182
BEAMCON0:	EQU $DFF1DC

;Registri del CIA utilizzati
CIAAPRA		EQU $BFE001

START
	move.l	4,A6				;Apre la graphics.library
	moveq	#0,D0
	lea	GFX_Name,A1
	jsr	-$0228(A6)			;Exec _OpenLibrary.
	move.l	d0,A5				;Preserva il puntatore alla
	move.l	d0,_GfxBase
	move.l	$26(A5),OLDCOP			;CopperList originale.

	move.l	4,A6				;'Congela' il sistema.
	jsr	-$78(a6)			;Exec _Disable

	move.w	INTENAR,OLDINTENA		;Preserva l'INTENA.
	move.w	DMACONR,OLDDMACON		;Preserva il DMACON.
	move.w	#%0111111111111111,DMACON	;Spegne tutti i DMA.
	jsr	InitSprites			;Inizializza i puntatori sprite
	move.w	#%1000001110100000,DMACON	;Accende solo il Copper DMA
						;e quello degli Sprites.
	move.w	#%0111111111111111,INTENA	;Spegne tutte le IRQ.
	move.l	#COP1,COP1LC			;Punta la nostra Copperlist.
	move.w	#PALSYNC,BEAMCON0		;Attiva il modo televisivo PAL
WaitClick
	btst	#6,CIAAPRA			;Se e' premuto il tasto
	beq	Exit				;sinistro del mouse esce.


	jsr	SetCoords			;Copia le coordinate nella
						;struttura sprite.
	jsr	ReadLPen			;Leggi la penna ottica.

	bra	WaitClick			;Ritorna al controllo del tasto
						;del mouse.
Exit

;Legge la sincronia dello schermo precedente (per risoluzioni particolari)
	move.l	_GfxBase,a6			;Assicurati che la graphics.lib
	cmp.w	#36,$14(a6)			;sia perlomeno V36 (kick 1.4).
	blo	NoViewExtra			;Altrimenti la ViewExtra non
						;puo' esistere.

	move.l	$22(a6),a0			;Prende la View attiva
	move.l	_GfxBase,a6			;Richiede eventuali estensioni.
	jsr	-702(a6)			;Gfx _GfxLookUp
	tst.l	d0				;Se sono nulle, non c'e nessuna
	beq	NoViewExtra			;ViewExtra.
	move.l	d0,a0				;Altrimenti:
	move.l	$1c(a0),a0			;Prende il puntatore al Monitor
	move.w	$28(a0),d0			;Legge la sincronia del Monitor
	move.w	d0,BEAMCON0			;e la copia nel registro di
						;sincronia hardware.
NoViewExtra:

	bset	#15,OLDINTENA			;Attiva il bit di controllo
	bset	#15,OLDDMACON			;nell'OLDINTENA e nell'OLDDMA.
	move.w	OLDINTENA,INTENA		;Ripristina l'INTENA.
	move.w	OLDDMACON,DMACON		;Ripristina il DMACON.

	move.l	OLDCOP,COP1LC			;Ripristina la Copperlist.

	move.l	4,A6				;'Scongela' il sistema.
	jsr	-$7e(a6)			;Exec _Enable

	move.l	_GfxBase,A1			;Chiude la graphics.library.
	move.l	4,a6
	jsr	-$019E(A6)			;Exec _CloseLibrary.

	rts					;Ritorna al DOS.

InitSprites
	lea	SpriteCopper,a0		;Prende l'indirizzo dei puntatori agli
					;sprites.
	move.l	#SPRITE1,d0		;Prende l'indirizzo dello Sprite1.
	move.w	d0,6(a0)		;Immette la word bassa.
	swap	d0			;Scambia le due word dell'indirizzo.
	move.w	d0,2(a0)		;Immette la word alta.

	add.w	#8,a0			;Fa avanzare il puntatore agli sprites.

	move.l	#SPRITENULL,d0		;Prende l'indirizzo dello Sprite vuoto.
	move.w	d0,6(a0)		;Immette la word bassa.
	swap	d0			;Scambia le due word dell'indirizzo.
	move.w	d0,2(a0)		;Immette la word alta.

	add.w	#8,a0			;Fa avanzare il puntatore agli sprites.

	move.l	#SPRITENULL,d0		;Prende l'indirizzo dello Sprite vuoto.
	move.w	d0,6(a0)		;Immette la word bassa.
	swap	d0			;Scambia le due word dell'indirizzo.
	move.w	d0,2(a0)		;Immette la word alta.

	add.w	#8,a0			;Fa avanzare il puntatore agli sprites.

	move.l	#SPRITENULL,d0		;Prende l'indirizzo dello Sprite vuoto.
	move.w	d0,6(a0)		;Immette la word bassa.
	swap	d0			;Scambia le due word dell'indirizzo.
	move.w	d0,2(a0)		;Immette la word alta.

	add.w	#8,a0			;Fa avanzare il puntatore agli sprites.

	move.l	#SPRITENULL,d0		;Prende l'indirizzo dello Sprite vuoto.
	move.w	d0,6(a0)		;Immette la word bassa.
	swap	d0			;Scambia le due word dell'indirizzo.
	move.w	d0,2(a0)		;Immette la word alta.

	add.w	#8,a0			;Fa avanzare il puntatore agli sprites.

	move.l	#SPRITENULL,d0		;Prende l'indirizzo dello Sprite vuoto.
	move.w	d0,6(a0)		;Immette la word bassa.
	swap	d0			;Scambia le due word dell'indirizzo.
	move.w	d0,2(a0)		;Immette la word alta.

	add.w	#8,a0			;Fa avanzare il puntatore agli sprites.

	move.l	#SPRITENULL,d0		;Prende l'indirizzo dello Sprite vuoto.
	move.w	d0,6(a0)		;Immette la word bassa.
	swap	d0			;Scambia le due word dell'indirizzo.
	move.w	d0,2(a0)		;Immette la word alta.

	add.w	#8,a0			;Fa avanzare il puntatore agli sprites.

	move.l	#SPRITENULL,d0		;Prende l'indirizzo dello Sprite vuoto.
	move.w	d0,6(a0)		;Immette la word bassa.
	swap	d0			;Scambia le due word dell'indirizzo.
	move.w	d0,2(a0)		;Immette la word alta.

	rts

ReadLpen:				;Esegue la lettura della penna ottica.
	move.l	VHPOSR,d0		;Si accerta che i contenuti dei due
	cmp.l	VHPOSR,d0		;registri VPOSR e VHPOSR siano
	bne	PenNotTriggered		;"congelati". Questo significa che la
					;penna ha intercettato il pennello
					;elettronico)
	move.l	d0,d1			;Toglie dalla lettura del registro VPOS
	and.l	#$0001ffff,d1		;i bit che non ci interessano e si
	cmp.l	#$10500,d1		;accerta che i valori ottenuti siano
	bgt	PenNotTriggered		;congruenti.

	moveq	#0,d0
	move.b	VPOSR+1,d0		;Legge la coordinata X.
	and.b	#1,d0
	lsl.w	#8,d0
	move.b	VHPOSR,d0
	sub.w	#52,d0			;La tara con il video.
	cmp.w	#$C0,d0			;Si accerta che lo sprite non vada
	blt	NoStopYPos		;troppo in basso.
	move.w	#$C0,d0
NoStopYPos:
	move.w	d0,Ypos
	move.b	VHPOSR+1,d0		;Legge la coordinata Y e la tara
	sub.w	#92,d0			;con il video.
	move.w	d0,Xpos
PenNotTriggered:
	rts

SetCoords			;Copia le coordinate dalle variabili nella
				;struttura sprite.
	lea	SPRITE1,a0
	move.w	XPos,d0		;Prende la X.
	add.b	#70,d0		;Ci somma l'OffSet del video.
	move.b	d0,1(a0)	;Lo immette in HSTART della struttura sprite.

	move.w	YPos,d0		;Prende la Y.
	add.b	#44,d0		;Ci somma l'OffSet del video.
	move.b	d0,(a0)		;Lo immette in VSTART della struttura sprite.
	add.b	#HEIGHT,d0	;Ci somma l'altezza.
	move.b	d0,2(a0)	;La immette in VSTOP della struttura sprite.
	rts


XPos	dc.w 0			;Contiene la coordinata X dello sprite
YPos	dc.w 0			;Contiene la coordinata Y dello sprite

SPRITE1				;Struttura sprite
	DC.W $64C8,$7400	;Word di controllo
	DC.W $003F,$FFC0	;Dati
	DC.W $007F,$FF80
	DC.W $00FF,$FF00
	DC.W $01FF,$FE00
	DC.W $03FF,$FC00
	DC.W $07FF,$F800
	DC.W $0FFF,$F001
	DC.W $1FFF,$E003
	DC.W $3FFF,$C007
	DC.W $7FFF,$800F
	DC.W $FFFF,$001F
	DC.W $FFFF,$003F
	DC.W $FFFF,$007F
	DC.W $FFFF,$00FF
	DC.W $FFFF,$01FF
	DC.W $FFFF,$03FF
	DC.W $0000,$0000	;Terminatori


SPRITENULL			;Sprite vuoto
	DC.W 0,0		;Word di controllo (azzerate)


COP1						;Inizio della CopperList.
	DC.W $0001,$FFFE
	DC.W $0180,$0FFF,$0182,$0FFF		;Colore di fondo e #1 neri
	DC.W $00E0,$0000,$00E2,$0000		;I puntatori ai bitplane
						;possono essere indirizzati
						;a qualunque locazione visto
						;che l'immagine non sara'
						;visualizzata (colore Nero).

	DC.W $008E,$2C81,$0090,$2CC1		;Dimensiona lo schermo in
	DC.W $0092,$0038,$0094,$00D0		;modalita' standard 320x256.

	DC.W $0100,$1209			;Attiva un bitplane.

;----Settaggi per la compatibilita' con il Chipset AGA e ECS----
	DC.W $0102,$0224			;BPLCON1
	DC.W $0104,$0024			;BPLCON2
	DC.W $0106,$0C60			;BPLCON3
	DC.W $010C,$0011			;BPLCON4
	DC.W $01FC,$0000			;FMODE
;---------------------------------------------------------------

	DC.W $01A2,$0fff,$01A4,$00f0,$01A6,$0f00;Setta i colori dello sprite.

SpriteCopper:					;Puntatori agli sprite.
	DC.W $0120,$0000,$0122,$0000
	DC.W $0124,$0000,$0126,$0000
	DC.W $0128,$0000,$012A,$0000
	DC.W $012C,$0000,$012E,$0000
	DC.W $0130,$0000,$0132,$0000
	DC.W $0134,$0000,$0136,$0000
	DC.W $0138,$0000,$013A,$0000
	DC.W $013C,$0000,$013E,$0000


	DC.W $FFFF,$FFFE	;WAIT X=$FF Y=$FF (Fine della CopperList)

GFX_Name	dc.b "graphics.library",0,0	;Nome della graphics.library

VERSION		dc.b "$VER:Lpen 1.1 (15.10.93) By Fabrizio Farenga",0


	CNOP 0,2
OldMouseX	dc.w 0
OldMouseY	dc.w 0
OLDINTENA	dc.w 0				;Buffer per l'INTENA
OLDDMACON	dc.w 0				;Buffer per il DMACON
OLDCOP		dc.l 0				;Buffer per la CopperList
_GFxBase:	dc.l 0				;Base della graphics.library

 END
