 	;------------------------------------------------
	;       UFV - Arquitectura de Computadores	    
	;------------------------------------------------
	; Programación ensamblador Z80
	; Práctica 1 : Barras verticales
	; Cuatro posibles soluciones
	;------------------------------------------------
	; Curso 2021/2022 - Daniel León
	;------------------------------------------------

		DEVICE ZXSPECTRUM48
		org $8000						; inicio del programa - directiva de ensamblador (afecta al cálculo de etiquetas)
		
		di 								; Deshabilitar las interrupciones enmascarables		
		jp inicio4						; Elige el metodo : inicio1, inicio2 o inicio3



;----------------------------------------------------------------------------------------------------------------------
inicio1: ; Esta es una forma recorriendo 768 posiciones seguidas (vector de 1 dimensión)
		  ; además muestra las barras en el orden correcto, simplemente haciendo el complemento a 1 del color seleccionado
        ld hl, $5800					; Cargo inicio atributos
        ld bc, $300 					; $300 = 768 atributos
bucle1:	ld a, c 						; cargo c, que me dará el color en los bits 2 y 3
		dec a 							; pero ojo que tengo que restarle 1 para que sea 0..767
		rlca							; los muevo al sitio adecuado para paper (puedo hacer add a)
		;cpl                            ; Esta linea invierte los colores: 000->111; 001->110; 010->101; 011-> 100 ...
		and 0x38     					; borro el resto de bits para dejar solo el paper
		ld (hl),a 						; Transfiero a memoria de video
		inc hl							; hl a siguiente posición de atributos
		dec bc 							; uno menos en el contador
		ld a,b
		or c                            ; Flag Z solo si B=0 Y C=0	
		jr nz, bucle1					; ciclar las 768 veces

		jp final						; Saltar al final del programa



;----------------------------------------------------------------------------------------------------------------------
inicio2: ; Esta otra forma prescinde del registro BC y compara el valor de H (del registro HL) con $5B para detener el bucle
 		ld hl, $5800					; Cargo inicio atributos
bucle2:	ld a, l 						; cargo l, que me dará el color en los bits 2 y 3
		add a							; los muevo al sitio adecuado para paper (podría rotar con RLCA)
		and 0x38     					; borro el resto de bits para dejar solo el paper
		;or $40							; Si queremos brillo, descomentar esta linea
		ld (hl),a 						; Transfiero a memoria de video
		inc hl							; hl a siguiente posición de atributos
		ld a, h 						; Comparo si H ha llegado a $5B (la primera vez que llegue, sera en $5B00)
		cp $5B

		jp final						; Saltar al final del programa



;----------------------------------------------------------------------------------------------------------------------
inicio3: ; Esta es otra forma recorriendo las coordenadas X (0..31) y las coordenadas Y (0..23) 
		ld b, 24						; b llevará la coordenada y, con un bucle djnz
bucleY: ld c, 31						; c es el bucle interno. Así que inicializamos su valor, lo recorreremos de 31 a 0, incluído
										
				
bucleX:	; Calcular la posición de pantalla para escribir
		; Esto podría sobrar puesto que sabemos que es lineal desde $5800,
		; Pero por motivos académicos vamos a calcularlo cada vez
		; La posición es: $5800 + Y*32 + X

		ld h,0 
		ld l,b  						; Para multiplicar b (coord. Y) por 32, vamos a hacer sumas. Esto se puede hacer en un bucle también
		dec l 							; pero ojo que tenemos que pasar de nuestra cuenta 32..1 a base 0: 31..0
		add hl, hl 						; ahora tenemos 2*b
		add hl, hl 						; ahora tenemos 4*b
		add hl, hl 						; ahora tenemos 8*b
		add hl, hl 						; ahora tenemos 16*b
		add hl, hl 						; ahora tenemos 32*b 
		
		ld d,0
		ld e,c    						; DE Contiene el valor de la coordenada X

		add hl, de 						; Ahora HL Contiene 32*y+X
		ld de, $5800
		add hl, de 						; Ahora HL contiene $5800 + 32*Y + X, el valor buscado, 

		 ; Calculo el color a partir de la coordenada X
		ld a, c 						; cargo c, que me dará el color en los bits 2 y 3
		rlca							; los muevo al sitio adecuado para paper
		and 0x38     					; borro el resto de bits para dejar solo el paper
		ld (hl),a 						; Transfiero a memoria de video

		dec c
		jp p, bucleX					; Fin del bucle interno.. lo hace con valores 31,30,29...2,1,0 y, cuando es -1, ya no lo hace
		djnz bucleY						; Fin del bucle externo

		jp final						; Saltar al final del programa
;----------------------------------------------------------------------------------------------------------------------
inicio4: ; Otra forma más. Ahora mando de 4 en 4 las escrituras y hago un bucle de 768/4

		ld hl, $5800					; Dirección de pantalla
		ld c,2			; Color

bucle4:	ld b, 4					; Voy a escribir 4 cuadros
cuatro: ld a, c 						; pero tengo que mover el color a la posición de paper -> Multiplicar por 8
		add a
		add a 
		add a 
		ld (hl), a  					; Escribo
		inc hl 							; Incremento
		djnz cuatro 					; Bucle for
		inc c							; Siguiente color
		ld a, c 						; paso c al registro a para hacer la operación módulo 8
		and 7							; esto es un módulo 8, ya que sólo me quedo con los 3 bits bajos, 0..7
		ld c, a 						; vuelvo a dejar el color en C
		ld a, h 						; compruebo que no he llegado al final de la zona de pantalla
		cp $5B
		jr nz, bucle4

		jp final



final: 	and 7							; borde de colores
		out ($FE),a
		inc a

		jr final						; Salto relativo incondicional a final (bloqueo del programa)												
