; abrir una pantalla via hardware
; por xele/intense
; basado en el source y explicaciones de SPANISH ARCHER
 
;formula para hallar la longitud de un bitmap :
; (ancho/8)*alto*no de bitplanes


picsize = 45960			;bytes que ocupa una pantalla de 4 bitplanes
execbase = 4			;base de la exec
allocmem = -$c6			;offset de la funcion reserva memoria
				;parametros: d0= cantidad memoria bytes
				;	     d1= tipo de memoria
				;#$10002 - chip		#$10004 - fast


	move.l	execbase,a6	;cargar a6 con la execbase
	move.l	#picsize,d0	;bytes areservar
	move.l	#$10002,d1	;tipo de memoria = chip
	jsr	allocmem(a6)	;salto a subrutina (offset) a partir de a6

	move.l	d0,bp0		;la funcion devuelve en d0 la direccion
				;de comienzo de la memoria reservada
				;aqui la pasamos a bp0 (bitplane 0)

	move.l	#listacopper,d1	;en d1 el inicio de la copperlist
	move.l	#listacopperfin,d0	;en d0 la direccion final
	sub.l	d1,d0		; restamos y tenemos lo que ocupa en d0
	move.l	d0,copperlong	; pasamos la longitud a copperlong

	move.l	#$10002,d1	;vamos a reservar memoria para la copperlist
	jsr	allocmem(a6)	;saltamos a allocmem

	move.l	d0,copperl	;nos devuelve en d0 la direccion de
				;comienzo de la memoria reservada

; ahora hay que meter las direcciones de los bitplanes

	move.l	bp0,d0		;volvemos a meter en d0 la var. bp0
	add.l	#10240,d0	;le sumamos #10240, lo que ocupa un bitplane
	move.l	d0,bp1		;y d0 lo metemos en el bitplane 1 (bp1)
	add.l	#10240,d0	;repetimos el proceso para el next plane
	move.l	d0,bp2		;ya tenemos el bp2 ,solo queda uno!
	add.l	#10240,d0	;y otra vez lo mismo
	move.l	d0,bp3		;ya los tenemos todos!

	move.l	bp0,d0		;d0 vale bp0
	move.w	d0,cbp05	;pasamos el valor a la copperlist. d0 va a
				;ser la segunda palabra de la instruccion
				;MOVE del copper que refresca el registro
				;del bitplane 0 (aqui la parte baja) ($0E2)
	swap	d0		;intercambia las words de d0
	move.w	d0,cbp0		;ahora escribe la parte alta ($0E0)


	move.l	bp1,d0		;d0 vale bp1
	move.w	d0,cbp15	;parte baja del bp1 a la copperlist ($0E6)
	swap	d0		;intercambia d0
	move.w	d0,cbp1		;parte alta del bp1 a la copperlist ($0E4)


	move.l	bp2,d0		;repetimos el proceso...
	move.w	d0,cbp25	;
	swap	d0		;
	move.w	d0,cbp2		;


	move.l	bp3,d0		;
	move.w	d0,cbp35	;
	swap	d0		;
	move.w	d0,cbp3		;

;vamos a abrir la graphics library para obtener la direccion de la lista
;copper actual y recuperarla una vez hayamos terminado el programa
;funcion openlib = -$198


	movea.l	execbase,a6	;base exec en a6
	lea	grafname,a1	;cargamos a1 con el nombre de la libreria
	clr.l	d0		;d0 lo ponemos a 0
	jsr	-$198(a6)	;salto a la funcion
	move.l	d0,grafbase	;pone la grafbase a 0




;vamos a pasar la copperlist a memoria CHIP

	movea.l	copperl,a0	;direccion donde vamos a meter la coperlist
	lea	listacop,a1	;direccion donde esta ahora mismo la  " 
	move.l	copperlong,d2	;longitud de la copperlist en bytes
bucle	move.b	(a1)+,(a0)+	;copiamos lo que hay en a1 en a0
	subi	#1,d2		;restamos 1 al contador d2
	bne	bucle		;si no ha llegado a 0 volvemos a bucle

; ahora una tonteria de nada: los registros hardware son offset de la
; direccion Custom ( $DFF000 ) por lo que para acceder a ellos hay que
; sumarle el offset al custom y  ESTO ES IMPORTANTE

; bueno , ahora desconectamos el DMA

	move.w	#$01a0,$dff096	; registro DMACONW = $096

; aqui escribimos a los siguientes Bits del DMACONW
; bit  15 			-lo borramos y todos los que estan a 1 valen 0
; bits 14,13,12,11,10		-los borramos , no nos sirven
; bit  09			-lo borramos y desconectamos el DMA
; bit  08			-conectado el DMA de bitplanes
; bit  07			-conectado el DMA del copper
; bit  05			-conectado el DMA de sprites
; bit  06,04,03,02,01,00	-deconectados, no sirven ahora


;ahora informamos al copper sobre donde esta la lista
;hay que escribir el registro de localizacion COP1LCH con la
;direccion de la copperlist
;la direccion strobe de salto COPJMP1 debe ser puesta a 0

cop1lch = $080
copconw = $088	; es lo mismo que COPJMP1

	move.l	copperl,$dff000+cop1lch	; registro de localicacion ok!
	clr.l	$dff000+copconw		; registro strobe borrado
					; con esto el copper es activado

;ahora hay que indicar la posicion y medidas de la ventana de vizualizacion
;primero, la posicion inicial,que se indica mediante el registro DIWSTRT
;(display window Start) es una word , el byte alto es la posicion Horizontal
;y el byte bajo la vertical
;ahora ponemos la posicion final, que se indica mediante el reg. DIWSTOP
;funciona igual que el de antes
	
diwstrt = $08E
diwstop = $090

	move.w	#$3081,$dff000+diwstrt	;Hpos=$30	Vpos=$81
	move.w	#$30c1,$dff000+diwstop	;

;ahora hay que informar del data-fetch es decir donde han de colocarse los
;datos de la memoria, esto se hace mediante el DDFSTRT y el DDFSTOP
;los valores normales son DDFSTRT=$38 y DDFSTOP=$D0

ddfstrt	= $092
ddfstop	= $094
	
	move.w	#$0038,$dff000+ddfstrt	;data fetch normal en baja resol.
	move.w	#$00d0,$dff000+ddfstop	;data fetch normal

;ahora hay que informar del tipo de pantalla 
;para eso necesitamos el registro BPLCON0 = $100
;los bits de este registro son:

;BIT	Nombre		funcion
;====================================================================
;15	Hires		activa alta resolucion (poniendolo a 1)
;14	bpu2		estos tres bits indican el numero de
;13	bpu1		bitplanes (max 6)
;12	bpu0		
;11	homod		activa modo ham
;10	dblpf		activa dual-playfield
;9	color		activa color
;8	gaud		audio para genlock
;7,6,5,4		no usados
;3	lpen		activa lapiz optico
;2	lace		activa entrelazado de lineas
;1	ersy		sincronizacion externa
;0      no usado 


;nuestra pantalla va a ser en baja resolucion,4 bitplanes y color activo
;por tanto BPLCON0 es $4200 (bits 14 y 9) activos

bplcon0 = $100

	move.w	#$4200,$dff000+bplcon0

;ahora vamonos con los modulos
;el modulo indica los bytes que hay entre la ultima word de una linea
;y la primera word de la siguiente linea
;para no entrelazado vale 0 y para interlace vale 40
;hay dos registros de modulo ,para planos impares y pares
;simplemente se ponen a 0



	clr.w	$dff108		;bpl1mod
	clr.w	$dff10a		;bpl2mod

;por ultimo nos queda escribir en los registros de scroll BPLCON1
;y en el de prioridad BPLCON2
;simplemente ponerlos a 0

	clr.w	$dff102		;bplcon1
	clr.w	$dff104		;bplcon2

;y ya esta casi todo a punto (joder con la pantallita)
;nos falta activar el famoso DMA
;para ello escribimos el bit 15 del DMACONW (SET/CLR)
;ademas del 10, activamos el 9 (DMAEN) y el 8 (DMA de bitplanes)
;y despues activamos el 7 (DMA del copper) y el 6 (DMA del blitter)

	move.w	#$87c0,$dff096	;activamos DMA

;y ahora si se quiere se cambian los colores

	move.w	#$F00,$dff182	;color rojo para la tinta
				;registro color01 = $182

;pantalla over, ahora empieza tu programa

	movea.l	bp0,a0		;esto es un peguito para dibujar
	move.w	#2500,d0	;de manera chunga unas lineas verticales
linea	move.l	#$55555555,(a0)+	;aqui escribimos en el bitplane 0
	sub.w	#1,d0
	bne	linea	
	
loop
	btst.b	#6,$bfe001	;este pego sirve para esperar el boton
	bne	loop		;izquierdo del raton

salida	move.l	grafbase,a4	;carga la direccion de la copperlist 
				;obtenida al abrir la graphics lib, en a4				

;como la base de la lista copper del DOS esta 38 posiciones de memoria (L)
;despues de la grafbase,mediante un dseplazamiento relativo ,vuelvo a
;escribir el registro de localizacion (haz memoria) del copper y despues
;vuelvo a escribir el registro strobe del copper.  

;despues liberamos toda la memoria que hemos utilizado , la reservada para
;la copperlist (copperlong) y para la pantalla (picsize)

	move.l	38(a4),$dff080
	clr.w	$dff000+copconw
	move.w	#$8060,$dff096	;desactiva DMA

;liberar memoria

	movea.l	4,a6
	move.l	copperl,a1	;direccion de copperlist en a1
	move.l	copperlong,d0	;longitud del bloque a liberar
	jsr	-$d2(a6)	;llamada a freemem
	move.l	bp0,a1		;direccion de la pantalla
	move.l	#picsize,d0	;longitud de memoria a liberar
	jsr	-$d2(a6)	;funcion freemem

;por ultimo , cerramos la graphics.library

	move.l	grafbase,a1	;a1 es la base de la libreria
	jsr	-$19e(a6)	;llamada a closelibrary

	clr.l	d0
	rts	
;---------------------------------------------------------------
;lista copper
;es muy sencilla ,solo refresca los registros de bitplanes
;esta compuesta por unos cuantos MOVEs a los registros (parte baja y
;parte alta) y finalmente un WAIT que nunca se cumple	

listacopper
listacop	dc.w	$0001,$ff00	;wait a la linea 0
		dc.w	$0180,$00f0	;color 0 verde intenso

		dc.w	$e0
cbp0		ds.w	1	;reservamos espacio porque aqui se va a escribir
		dc.w	$e2	;la direccion del bitplane 0
cbp05		ds.w	1
		dc.w	$e4
cbp1		ds.w	1
		dc.w	$e6
cbp15		ds.w	1
		dc.w	$e8
cbp2		ds.w	1
		dc.w	$ea
cbp25		ds.w	1
		dc.w	$ec
cbp3		ds.w	1
		dc.w	$ee
cbp35		ds.w	1
		dc.w	$9601,$ff00	;wait a la linea 150
		dc.w	$0180,$00c0	;color 0 a verde
		dc.w	$ffff,$fffe
listacopperfin


;reserva de espacio para variables

bp0		ds.l	1
bp1		ds.l	1
bp2		ds.l	1
bp3		ds.l	1
copperl		ds.l	1
copperlong	ds.l	1
grafbase	ds.l	1
grafname	dc.b	'graphics.library',0
		end
