aboutsummaryrefslogtreecommitdiff
path: root/lib/cpcrslib/cpc_GphStr.s
diff options
context:
space:
mode:
authorJuan J. Martinez <jjm@usebox.net>2023-11-05 11:22:55 +0000
committerJuan J. Martinez <jjm@usebox.net>2023-11-05 11:31:28 +0000
commit2fbdf974338bde8576efdae40a819a76b2391033 (patch)
tree64d41a37470143f142344f9a439d96de3e7918c2 /lib/cpcrslib/cpc_GphStr.s
downloadkitsunes-curse-2fbdf974338bde8576efdae40a819a76b2391033.tar.gz
kitsunes-curse-2fbdf974338bde8576efdae40a819a76b2391033.zip
Initial import of the open source release
Diffstat (limited to 'lib/cpcrslib/cpc_GphStr.s')
-rw-r--r--lib/cpcrslib/cpc_GphStr.s700
1 files changed, 700 insertions, 0 deletions
diff --git a/lib/cpcrslib/cpc_GphStr.s b/lib/cpcrslib/cpc_GphStr.s
new file mode 100644
index 0000000..3f656fa
--- /dev/null
+++ b/lib/cpcrslib/cpc_GphStr.s
@@ -0,0 +1,700 @@
+; ******************************************************
+; ** Librería de rutinas SDCC para Amstrad CPC **
+; ** Raúl Simarro (Artaburu) - 2009, 2012 **
+; ******************************************************
+
+
+
+cpc_GetScrAddress0: ;en HL están las coordenadas
+
+ ;LD A,H
+ LD (#inc_ancho+1),A
+ LD A,L
+ SRL A
+ SRL A
+ SRL A
+ ; A indica el bloque a multiplicar x &50
+ LD D,A ;D
+ SLA A
+ SLA A
+ SLA A
+ SUB L
+ NEG
+ ; A indica el desplazamiento a multiplicar x &800
+ LD E,A ;E
+ LD L,D
+ LD H,#0
+ ADD HL,HL
+ LD BC,#bloques
+ ADD HL,BC
+ ;HL APUNTA AL BLOQUE BUSCADO
+ LD C,(HL)
+ INC HL
+ LD H,(HL)
+ LD L,C
+ ;HL TIENE EL VALOR DEL BLOQUE DE 8 BUSCADO
+ PUSH HL
+ LD D,#0
+ LD HL,#sub_bloques
+ ADD HL,DE
+ LD A,(HL)
+ POP HL
+ ADD H
+ LD H,A
+inc_ancho:
+ LD E,#0
+ ADD HL,DE
+ RET
+
+bloques:
+.DW #0XC000,#0XC050,#0XC0A0,#0XC0F0,#0XC140,#0XC190,#0XC1E0,#0XC230,#0XC280,#0XC2D0,#0XC320,#0XC370,#0XC3C0,#0XC410,#0XC460,#0XC4B0,#0XC500,#0XC550,#0XC5A0,#0XC5F0,#0XC640,#0XC690,#0XC6E0,#0XC730,#0XC780
+sub_bloques:
+.DB #0X00,#0X08,#0X10,#0X18,#0X20,#0X28,#0X30,#0X38
+
+
+
+
+;*************************************
+; GRAPHIC TEXT
+;*************************************
+
+.globl _cpc_PrintGphStr2X
+
+_cpc_PrintGphStr2X::
+;preparación datos impresión. El ancho y alto son fijos!
+ LD IX,#2
+ ADD IX,SP
+ LD L,2 (IX)
+ LD H,3 (IX) ;DESTINO
+ LD E,0 (IX)
+ LD D,1 (IX) ;TEXTO ORIGEN
+ LD A,#1
+ JP cpc_PrintGphStr0
+
+
+
+.globl _cpc_PrintGphStrXY2X
+
+_cpc_PrintGphStrXY2X::
+;preparación datos impresión. El ancho y alto son fijos!
+ LD IX,#2
+ ADD IX,SP
+ LD L,3 (IX)
+ LD A,2 (IX) ;pantalla
+ CALL cpc_GetScrAddress0
+ LD E,0 (IX)
+ LD D,1 (IX) ;texto origen
+ LD A,#1
+ JP cpc_PrintGphStr0
+
+.globl _cpc_PrintGphStrXY
+
+_cpc_PrintGphStrXY::
+;preparación datos impresión. El ancho y alto son fijos!
+ LD IX,#2
+ ADD IX,SP
+ LD L,3 (IX)
+ LD A,2 (IX) ;pantalla
+ CALL cpc_GetScrAddress0
+ LD E,0 (IX)
+ LD D,1 (IX) ;texto origen
+ JP cpc_PrintGphStr0
+
+
+.globl _cpc_PrintGphStr
+
+_cpc_PrintGphStr::
+;preparación datos impresión. El ancho y alto son fijos!
+ LD IX,#2
+ ADD IX,SP
+ LD L,2 (IX)
+ LD H,3 (IX) ;DESTINO
+ ;LD (CPC_PRINTGPHSTR0+DIRECC_DESTINO0),HL
+ LD E,0 (IX)
+ LD D,1 (IX) ;TEXTO ORIGEN
+ ;JP cpc_PrintGphStr0
+
+cpc_PrintGphStr0:
+
+ ;DE destino
+ ;HL origen
+ ;ex de,hl
+ LD (#doble),A
+ ;trabajo previo: Para tener una lista de trabajos de impresión. No se interrumpe
+ ;la impresión en curso.
+ LD A,(#imprimiendo)
+ CP #1
+ JP Z,add_elemento
+ LD (#direcc_destino),HL
+ EX DE,HL
+ CALL bucle_texto0
+
+;antes de terminar, se mira si hay algo en cola.
+bucle_cola_impresion:
+ LD A,(#elementos_cola)
+ OR A
+ JP Z,terminar_impresion
+ CALL leer_elemento
+ JP bucle_cola_impresion
+
+
+terminar_impresion:
+ XOR A
+ LD (#imprimiendo),A
+ RET
+entrar_cola_impresion:
+;si se está imprimiendo se mete el valor en la cola
+ RET
+add_elemento:
+ DI
+ LD IX,(#pos_cola)
+ LD 0 (IX),L
+ LD 1 (IX),H
+ LD 2 (IX),E
+ LD 3 (IX),D
+ INC IX
+ INC IX
+ INC IX
+ INC IX
+ LD (#pos_cola),IX
+
+ LD HL,#elementos_cola
+ INC (HL)
+ ;Se añaden los valores hl y de
+ EI
+ RET
+leer_elemento:
+ DI
+ LD IX,(#pos_cola)
+ LD L,0 (IX)
+ LD H,1 (IX)
+ LD E,2 (IX)
+ LD D,4 (IX)
+ DEC IX
+ DEC IX
+ DEC IX
+ DEC IX
+ LD (#pos_cola),IX
+ LD HL,#elementos_cola
+ DEC (HL)
+ EI
+ RET
+
+elementos_cola:
+ .DW #0 ; defw 0
+pos_cola:
+ .DW #cola_impresion ;defw cola_impresion
+ ;pos_escritura_cola defw cola_impresion
+cola_impresion: ; defs 12
+ .DB #0,#0,#0,#0,#0,#0,#0,#0,#0,#0,#0,#0
+bucle_texto0:
+ LD A,#1
+ LD (imprimiendo),A
+
+ LD A,(first_char)
+ LD B,A ;resto 48 para saber el número del caracter (En ASCII 0=48)
+
+ LD A,(HL)
+ OR A ;CP 0
+ RET Z
+ SUB B
+ LD BC,(#cpc_Chars) ;apunto a la primera letra
+ PUSH HL
+
+ LD L,A ;en A tengo la letra que sería
+ LD H,#0
+ ADD HL,HL
+ ADD HL,HL
+ ADD HL,HL ;x8 porque cada letra son 8 bytes
+ ADD HL,BC ;ahora HL apunta a los datos de la letra correspondiente
+ CALL escribe_letra
+ LD A,(doble)
+ CP #1
+; ANTES DE IMPRIMIR SE CHEQUEA SI ES DE ALTURA EL DOBLE Y SE ACTÚA EN CONSECUENCIA
+ CALL Z, doblar_letra
+ LD HL,(#direcc_destino)
+ LD A,(doble)
+ CP #1
+ ;alto
+ JR Z,cont_doble
+ LD DE,#letra_decodificada
+ .DB #0xfD
+ LD H,#8 ;ALTO, SE PUEDE TRABAJAR CON HX DIRECTAMENTE
+ JR cont_tot
+
+
+cont_doble:
+ LD DE,#letra_decodificada_tmp
+ .DB #0xfD
+ LD H,#16 ;ALTO, SE PUEDE TRABAJAR CON HX DIRECTAMENTE
+
+cont_tot:
+ CALL cpc_PutSp0
+ LD HL,(#direcc_destino)
+ INC HL
+ INC HL
+ LD (#direcc_destino),HL
+ POP HL
+ INC HL
+ JP bucle_texto0
+
+
+doble:
+ .DB #0
+imprimiendo:
+ .DB #0
+direcc_destino:
+ .DW #0
+
+
+cpc_PutSp0:
+; .DB #0xfD
+; LD H,16 ;ALTO, SE PUEDE TRABAJAR CON HX DIRECTAMENTE
+ LD B,#7
+ LD C,B
+loop_alto_2:
+
+loop_ancho_2:
+ EX DE,HL
+ LDI
+ LDI
+ .DB #0XFD
+ DEC H
+ RET Z
+ EX DE,HL
+salto_linea:
+ LD C,#0XFE ;&07F6 ;SALTO LINEA MENOS ANCHO
+ ADD HL,BC
+ JP NC,loop_alto_2 ;SIG_LINEA_2ZZ ;SI NO DESBORDA VA A LA SIGUIENTE LINEA
+ LD BC,#0XC050
+ ADD HL,BC
+ LD B,#7 ;SÓLO SE DARÍA UNA DE CADA 8 VECES EN UN SPRITE
+ JP loop_alto_2
+
+
+
+
+doblar_letra:
+ LD HL,#letra_decodificada
+ LD DE,#letra_decodificada_tmp
+ LD B,#8
+buc_doblar_letra:
+ LD A,(HL)
+ INC HL
+ LD (DE),A
+ INC DE
+ INC DE
+ LD (DE),A
+ DEC DE
+ LD A,(HL)
+ INC HL
+ LD (DE),A
+ INC DE
+ INC DE
+ LD (DE),A
+ INC DE
+ DJNZ buc_doblar_letra
+ RET
+
+
+escribe_letra: ; Code by Kevin Thacker
+ PUSH DE
+ LD IY,#letra_decodificada
+ LD B,#8
+bucle_alto_letra:
+ PUSH BC
+ PUSH HL
+ LD E,(HL)
+ CALL op_colores
+ LD (IY),D
+ INC IY
+ CALL op_colores
+ LD (IY),D
+ INC IY
+ POP HL
+ INC HL
+ POP BC
+ DJNZ bucle_alto_letra
+ POP DE
+ RET
+
+op_colores:
+ ld d,#0 ;; initial byte at end will be result of 2 pixels combined
+ CALL op_colores_pixel ;; do pixel 0
+ RLC D
+ CALL op_colores_pixel
+ RRC D
+ RET
+
+;; follow through to do pixel 1
+
+op_colores_pixel:
+ ;; shift out pixel into bits 0 and 1 (source)
+ RLC E
+ RLC E
+ ;; isolate
+ LD A,E
+ AND #0X3
+ LD HL,#colores_b0
+ ADD A,L
+ LD L,A
+ LD A,H
+ ADC A,#0
+ LD H,A
+ ;; READ IT AND COMBINE WITH PIXEL SO FAR
+ LD A,D
+ OR (HL)
+ LD D,A
+ RET
+
+
+.globl _cpc_SetInkGphStr
+
+_cpc_SetInkGphStr::
+;preparación datos impresión. El ancho y alto son fijos!
+ LD IX,#2
+ ADD IX,SP
+
+ ;LD A,H
+ ;LD C,L
+ LD A,1 (IX) ;VALOR
+ LD C,0 (IX) ;COLOR
+
+ LD HL,#colores_b0
+ LD B,#0
+ ADD HL,BC
+ LD (HL),A
+ RET
+
+
+
+
+
+.globl _cpc_PrintGphStrXYM1
+
+_cpc_PrintGphStrXYM1::
+;preparación datos impresión. El ancho y alto son fijos!
+ LD IX,#2
+ ADD IX,SP
+ LD L,3 (IX)
+ LD A,2 (IX) ;pantalla
+ CALL cpc_GetScrAddress0
+ LD E,0 (IX)
+ LD D,1 (IX) ;texto origen
+ XOR A
+ JP cpc_PrintGphStr0M1
+
+
+.globl _cpc_PrintGphStrXYM12X
+
+_cpc_PrintGphStrXYM12X::
+;preparación datos impresión. El ancho y alto son fijos!
+ LD IX,#2
+ ADD IX,SP
+ LD L,3 (IX)
+ LD A,2 (IX) ;pantalla
+ CALL cpc_GetScrAddress0
+ LD E,0 (IX)
+ LD D,1 (IX) ;texto origen
+ LD A,#1
+ JP cpc_PrintGphStr0M1
+
+
+
+
+.globl _cpc_PrintGphStrM12X
+
+_cpc_PrintGphStrM12X::
+ LD IX,#2
+ ADD IX,SP
+ LD L,2 (IX)
+ LD H,3 (IX) ;DESTINO
+ LD E,0 (IX)
+ LD D,1 (IX) ;TEXTO ORIGEN
+ LD A,#1
+
+ JP cpc_PrintGphStr0M1
+
+
+
+.globl _cpc_PrintGphStrM1
+
+_cpc_PrintGphStrM1::
+;preparación datos impresión. El ancho y alto son fijos!
+
+ LD IX,#2
+ ADD IX,SP
+ LD L,2 (IX)
+ LD H,3 (IX) ;DESTINO
+ LD E,0 (IX)
+ LD D,1 (IX) ;TEXTO ORIGEN
+ XOR A
+
+ ;JP cpc_PrintGphStr0M1
+
+cpc_PrintGphStr0M1:
+ ;DE destino
+ ;HL origen
+ ;ex de,hl
+ LD (#dobleM1),A
+ ;trabajo previo: Para tener una lista de trabajos de impresión. No se interrumpe
+ ;la impresión en curso.
+ LD A,(#imprimiendo)
+ CP #1
+ JP Z,add_elemento
+ LD (#direcc_destino),HL
+ EX DE,HL
+ CALL bucle_texto0M1
+;antes de terminar, se mira si hay algo en cola.
+bucle_cola_impresionM1:
+ LD A,(#elementos_cola)
+ OR A
+ JP Z,terminar_impresion
+ CALL leer_elemento
+ JP bucle_cola_impresionM1
+
+
+
+
+
+bucle_texto0M1:
+ LD A,#1
+ LD (#imprimiendo),A
+
+ LD A,(#first_char)
+ LD B,A ;resto 48 para saber el número del caracter (En ASCII 0=48)
+ LD A,(HL)
+ OR A ;CP 0
+ RET Z
+ SUB B
+ LD BC,(#cpc_Chars) ;apunto a la primera letra
+ PUSH HL
+ LD L,A ;en A tengo la letra que sería
+ LD H,#0
+ ADD HL,HL
+ ADD HL,HL
+ ADD HL,HL ;x8 porque cada letra son 8 bytes
+ ADD HL,BC ;ahora HL apunta a los datos de la letra correspondiente
+ CALL escribe_letraM1
+ LD A,(dobleM1)
+ CP #1
+ ; ANTES DE IMPRIMIR SE CHEQUEA SI ES DE ALTURA EL DOBLE Y SE ACTÚA EN CONSECUENCIA
+ CALL Z, doblar_letraM1
+ LD HL,(direcc_destino)
+ LD A,(dobleM1)
+ CP #1
+ ;alto
+ JR Z,cont_dobleM1
+ LD DE,#letra_decodificada
+ .DB #0xfD
+ LD H,#8 ;ALTO, SE PUEDE TRABAJAR CON HX DIRECTAMENTE
+ JR cont_totM1
+
+
+cont_dobleM1:
+ LD DE,#letra_decodificada_tmp
+ .DB #0XFD
+ LD H,#16 ;ALTO, SE PUEDE TRABAJAR CON HX DIRECTAMENTE
+cont_totM1:
+ CALL cpc_PutSp0M1
+ LD HL,(#direcc_destino)
+ INC HL
+ LD (#direcc_destino),HL
+ POP HL
+ INC HL
+ JP bucle_texto0M1
+
+dobleM1:
+ .DB #0
+;.imprimiendo defb 0
+;.direcc_destino defw 0
+
+doblar_letraM1:
+ LD HL,#letra_decodificada
+ LD DE,#letra_decodificada_tmp
+ LD B,#8
+buc_doblar_letraM1:
+ LD A,(HL)
+ INC HL
+ LD (DE),A
+ INC DE
+ LD (DE),A
+ INC DE
+ DJNZ buc_doblar_letraM1
+ RET
+
+
+cpc_PutSp0M1:
+ ; defb #0xfD
+ ; LD H,8 ;ALTO, SE PUEDE TRABAJAR CON HX DIRECTAMENTE
+ LD B,#7
+ LD C,B
+loop_alto_2M1:
+loop_ancho_2M1:
+ EX DE,HL
+ LDI
+ .DB #0XFD
+ DEC H
+ RET Z
+ EX DE,HL
+salto_lineaM1:
+ LD C,#0XFF ;#0x07f6 ;salto linea menos ancho
+ ADD HL,BC
+ JP NC,loop_alto_2M1 ;sig_linea_2zz ;si no desborda va a la siguiente linea
+ LD BC,#0XC050
+ ADD HL,BC
+ LD B,#7 ;sólo se daría una de cada 8 veces en un sprite
+ JP loop_alto_2M1
+
+
+
+escribe_letraM1:
+ LD IY,#letra_decodificada
+ LD B,#8
+ LD IX,#byte_tmp
+bucle_altoM1:
+ PUSH BC
+ PUSH HL
+
+ LD A,(HL)
+ LD HL,#dato
+ LD (HL),A
+ ;me deja en ix los valores convertidos
+ ;HL tiene la dirección origen de los datos de la letra
+ ;LD DE,letra ;el destino es la posición de decodificación de la letra
+ ;Se analiza el byte por parejas de bits para saber el color de cada pixel.
+ LD (IX),#0 ;reset el byte
+ LD B,#4 ;son 4 pixels por byte. Los recorro en un bucle y miro qué color tiene cada byte.
+bucle_coloresM1:
+ ;roto el byte en (HL)
+ PUSH HL
+ CALL op_colores_m1 ;voy a ver qué color es el byte. tengo un máximo de 4 colores posibles en modo 0.
+ POP HL
+ SRL (HL)
+ SRL (HL) ;voy rotando el byte para mirar los bits por pares.
+ DJNZ bucle_coloresM1
+ LD A,(IX)
+ LD (IY),A
+ INC IY
+ POP HL
+ INC HL
+ POP BC
+ DJNZ bucle_altoM1
+ RET
+
+
+;.rutina
+;HL tiene la dirección origen de los datos de la letra
+
+;Se analiza el byte por parejas de bits para saber el color de cada pixel.
+;ld ix,byte_tmp
+;ld (ix+0),0
+
+;LD B,4 ;son 4 pixels por byte. Los recorro en un bucle y miro qué color tiene cada byte.
+;.bucle_colores
+;roto el byte en (HL)
+;push hl
+;call op_colores_m1 ;voy a ver qué color es el byte. tengo un máximo de 4 colores posibles en modo 0.
+;pop hl
+;sla (HL)
+;sla (HL) ;voy rotando el byte para mirar los bits por pares.
+
+;djnz bucle_colores
+
+;ret
+op_colores_m1: ;rutina en modo 1
+ ;mira el color del bit a pintar
+ LD A,#3 ;hay 4 colores posibles. Me quedo con los 2 primeros bits
+ AND (HL)
+ ; EN A tengo el número de bytes a sumar!!
+ LD HL,#colores_m1
+ LD E,A
+ LD D,#0
+ ADD HL,DE
+ LD C,(HL)
+ ;EN C ESTÁ EL BYTE DEL COLOR
+ ;LD A,4
+ ;SUB B
+ LD A,B
+ DEC A
+ OR A ;CP 0
+ JP Z,_sin_rotar
+rotando:
+ SRL C
+ DEC A
+ JP NZ, rotando
+_sin_rotar:
+ LD A,C
+ OR (IX)
+ LD (IX),A
+ ;INC IX
+ RET
+
+
+.globl _cpc_SetInkGphStrM1
+
+_cpc_SetInkGphStrM1::
+ LD IX,#2
+ ADD IX,SP
+ LD A,1 (IX) ;VALOR
+ LD C,0 (IX) ;COLOR
+ LD HL,#colores_cambM1
+ LD B,#0
+ ADD HL,BC
+ LD (HL),A
+ RET
+
+
+
+colores_cambM1:
+colores_m1:
+ .DB #0b00000000,#0b10001000,#0b10000000,#0b00001000
+
+;defb @00000000, @01010100, @00010000, @00000101 ;@00000001, @00000101, @00010101, @00000000
+
+
+
+;DEFC direcc_destino0_m1 = direcc_destino
+;DEFC colores_cambM1 = colores_m1
+
+
+.globl _cpc_SetFont
+
+_cpc_SetFont::
+ ld ix, #2
+ add ix, sp
+ ld a, 0(ix)
+ ld (#first_char), a
+ ld l, 1(ix)
+ ld h, 2(ix)
+ ld (#cpc_Chars), hl
+ ret
+
+dato:
+ .DB #0b00011011 ;aquí dejo temporalmente el byte a tratar
+
+byte_tmp:
+ .DB #0
+ .DB #0
+ .DB #0 ;defs 3
+colores_b0: ;defino los 4 colores posibles para el byte. Los colores pueden ser cualesquiera.
+ ;Pero se tienen que poner bien, en la posición que le corresponda.
+ .DB #0b00001010,#0b00100000,#0b10100000,#0b00101000
+ ;.DB #0b00000000, #0b01010100, #0b00010000, #0b00000101 ;#0b00000001, #0b00000101, #0b00010101, #0b00000000
+
+letra_decodificada: ;. defs 16 ;16 ;uso este espacio para guardar la letra que se decodifica
+ .DB #0,#0,#0,#0,#0,#0,#0,#0
+ .DB #0,#0,#0,#0,#0,#0,#0,#0
+letra_decodificada_tmp: ;defs 32 ;16 ;uso este espacio para guardar la letra que se decodifica para tamaño doble altura
+ .DB #0,#0,#0,#0,#0,#0,#0,#0
+ .DB #0,#0,#0,#0,#0,#0,#0,#0
+ .DB #0,#0,#0,#0,#0,#0,#0,#0
+ .DB #0,#0,#0,#0,#0,#0,#0,#0
+
+
+first_char:
+ .DB #0 ;first defined char number (ASCII)
+
+cpc_Chars: ;cpc_Chars codificadas... cada pixel se define con 2 bits que definen el color.
+ .DW #0
+