ORG 35000 CALL ClearScreen_Pattern ; Establecemos los parametros de entrada a la rutina ; Los 2 primeros se pueden establecer una unica vez LD HL, bicho_gfx LD (DS_SPRITES), HL LD HL, bicho_attrib LD (DS_ATTRIBS), HL LD A, 13 LD (DS_COORD_X), A LD A, 8 LD (DS_COORD_Y), A XOR A LD (DS_NUMSPR), A CALL DrawSprite_16x16_LD loop: JR loop RET ; Variables que usaremos como parĂ¡metros DS_SPRITES DEFW 0 DS_ATTRIBS DEFW 0 DS_COORD_X DEFB 0 DS_COORD_Y DEFB 0 DS_NUMSPR DEFB 0 ;------------------------------------------------------------- ; DrawSprite_16x16_LD: ; Imprime un sprite de 16x16 pixeles con o sin atributos. ; ; Entrada (paso por parametros en memoria): ; Direccion Parametro ; (DS_SPRITES) Direccion de la tabla de Sprites ; (DS_ATTRIBS) Direccion de la tabla de Atribs (0=no atributos) ; (DS_COORD_X) Coordenada X en baja resolucion ; (DS_COORD_Y) Coordenada Y en baja resolucion ; (DS_NUMSPR) Numero de sprite a dibujar (0-N) ;------------------------------------------------------------- DrawSprite_16x16_LD: ; Guardamos en BC la pareja (x,y) -> B=COORD_Y y C=COORD_X LD BC, (DS_COORD_X) ;;; Calculamos las coordenadas destino de pantalla en DE: LD A, B AND $18 ADD A, $40 LD D, A LD A, B AND 7 RRCA RRCA RRCA ADD A, C LD E, A PUSH DE ; Lo guardamos para luego, lo usaremos para ; calcular la direccion del atributo ;;; Calcular posicion origen (array sprites) en HL como: ;;; direccion = base_sprites + (NUM_SPRITE*32) LD BC, (DS_SPRITES) LD A, (DS_NUMSPR) LD L, 0 ; AL = DS_NUMSPR*256 SRL A ; Desplazamos a la derecha para dividir por dos RR L ; AL = DS_NUMSPR*128 RRA ; Rotamos, ya que el bit que salio de L al CF fue 0 RR L ; AL = DS_NUMSPR*64 RRA ; Rotamos, ya que el bit que salio de L al CF fue 0 RR L ; AL = DS_NUMSPR*32 LD H, A ; HL = DS_NUMSPR*32 ADD HL, BC ; HL = BC + HL = DS_SPRITES + (DS_NUMSPR * 32) ; HL contiene la direccion de inicio en el sprite EX DE, HL ; Intercambiamos DE y HL (DE=origen, HL=destino) ;;; Repetir 8 veces (primeros 2 bloques horizontales): LD B, 8 drawsp16x16_loop1: LD A, (DE) ; Bloque 1: Leemos dato del sprite LD (HL), A ; Copiamos dato a pantalla INC DE ; Incrementar puntero en sprite INC L ; Incrementar puntero en pantalla LD A, (DE) ; Bloque 2: Leemos dato del sprite LD (HL), A ; Copiamos dato a pantalla INC DE ; Incrementar puntero en sprite INC H ; Hay que sumar 256 para ir al siguiente scanline DEC L ; pero hay que restar el INC L que hicimos. DJNZ drawsp16x16_loop1 ; Avanzamos HL 1 scanline (codigo de incremento de HL en 1 scanline) ; desde el septimo scanline de la fila Y+1 al primero de la Y+2 ;;;INC H ; No hay que hacer INC H, lo hizo en el bucle ;;;LD A, H ; No hay que hacer esta prueba, sabemos que ;;;AND 7 ; no hay salto (es un cambio de bloque) ;;;JR NZ, drawsp16_nofix_abajop LD A, L ADD A, 32 LD L, A JR C, drawsp16_nofix_abajop LD A, H SUB 8 LD H, A drawsp16_nofix_abajop: ;;; Repetir 8 veces (segundos 2 bloques horizontales): LD B, 8 drawsp16x16_loop2: LD A, (DE) ; Bloque 1: Leemos dato del sprite LD (HL), A ; Copiamos dato a pantalla INC DE ; Incrementar puntero en sprite INC L ; Incrementar puntero en pantalla LD A, (DE) ; Bloque 2: Leemos dato del sprite LD (HL), A ; Copiamos dato a pantalla INC DE ; Incrementar puntero en sprite INC H ; Hay que sumar 256 para ir al siguiente scanline DEC L ; pero hay que restar el INC L que hicimos. DJNZ drawsp16x16_loop2 ;;; En este punto, los 16 scanlines del sprite estan dibujados. POP BC ; Recuperamos el offset del primer scanline ;;; Considerar el dibujado de los atributos (Si DS_ATTRIBS=0 -> RET) LD HL, (DS_ATTRIBS) XOR A ; A = 0 ADD A, H ; A = 0 + H = H RET Z ; Si H = 0, volver (no dibujar atributos) ;;; Calcular posicion destino en area de atributos en DE. LD A, B ; Codigo de Get_Attr_Offset_From_Image RRCA ; Obtenemos dir de atributo a partir de RRCA ; dir de zona de imagen. RRCA ; Nos evita volver a obtener X e Y AND 3 ; y hacer el calculo completo de la OR $58 ; direccion en zona de atributos LD D, A LD E, C ; DE tiene el offset del attr de HL LD A, (DS_NUMSPR) ; Cogemos el numero de sprite a dibujar LD C, A LD B, 0 ADD HL, BC ; HL = HL+DS_NUMSPR ADD HL, BC ; HL = HL+DS_NUMSPR*2 ADD HL, BC ; HL = HL+DS_NUMSPR*3 ADD HL, BC ; HL = HL+HL=(DS_NUMSPR*4) = Origen de atributo LDI LDI ; Imprimimos las 2 primeras filas de atributo ;;; Avance diferencial a la siguiente linea de atributos LD A, E ; A = L ADD A, 30 ; Sumamos A = A + 30 mas los 2 INCs de LDI. LD E, A ; Guardamos en L (L = L+30 + 2 por LDI=L+32) JR NC, drawsp16x16_attrab_noinc INC D drawsp16x16_attrab_noinc: LDI LDI RET ; porque no necesitamos incrementar HL y DE ;-------------------------------------------------------------------- ; ClearScreen_Pattern ; Limpia la pantalla con patrones de pixeles alternados ;-------------------------------------------------------------------- ClearScreen_Pattern: LD B, 191 ; Numero de lineas a rellenar cs_line_loop: LD C, 0 LD A, B LD B, A CALL $22B1 ; ROM (Pixel-Address) LD A, B AND 1 JR Z, cs_es_par LD A, 170 JR cs_pintar cs_es_par: LD A, 85 cs_pintar: LD D, B ; Salvar el contador del bucle LD B, 32 ; Imprimir 32 bytes cs_x_loop: LD (HL), A INC HL DJNZ cs_x_loop LD B, D ; Recuperamos el contador externo DJNZ cs_line_loop ; Repetimos 192 veces RET ;----------------------------------------------------------------------- ;ASM source file created by SevenuP v1.20 ;GRAPHIC DATA: ;Pixel Size: ( 16, 64) ;Char Size: ( 2, 8) ;Sort Priorities: X char, Char line, Y char ;Data Outputted: Gfx+Attr ;Interleave: Sprite ;Mask: No ;----------------------------------------------------------------------- bicho_gfx: DEFB 8,128, 4, 64, 0, 0, 7,224 DEFB 15, 80, 15, 80, 15,240, 7,224 DEFB 0, 0, 1, 64, 0, 32, 2, 0 DEFB 104, 22,112, 14, 56, 28, 0, 0 bicho_attrib: DEFB 70, 71, 67, 3 END 35000