Snippets en Z80

Programando el Amstrad en Ensamblador.
Reglas del Foro
Debido a que hay varios temas pidiendo ayuda para programar en ensamblador máquinas distintas al Amstrad CPC, con micro distinto al Z80 y que incluso dependen del sistema operativo, nos vemos en la necesidad de poner por escrito que estos posts son bienvenidos pero que no es el lugar adecuado ya que por estos lares nos dedicamos más al ensamblador del Z80, un microprocesador de 8 bits que tuvo su gran auge en ordenadores y consolas de los años 80.

De todas formas, esto no quita que alguien que sepa del asunto pueda postear alguna respuesta pero es más fácil encontrar foros dedicados a programar en ensamblador en Windows o MS-DOS que ayudarán más que nosotros:
http://www.lawebdelprogramador.com/news ... nsamblador
Urusergi
Forum Addict
Forum Addict
Mensajes: 381
Registrado: Sab 25 Feb , 2006 5:45 pm

Re: Snippets en Z80

Mensajepor Urusergi » Dom 25 Sep , 2022 5:46 pm

Los códigos de control se emplean mucho en ensamblador con la llamada del firmware #bb5a precisamente.

La directiva 'str' me sonaba que existía, pero imagino que es más compatible con otros ensambladores si usamos 'db' y sumamos #80 al último carácter. Ahora bien, la directiva 'charset' no la conocía y es muy interesante, gracias \:D/

He aprovechado para currarme el set completo con 'charset' y aplicarlo a la última rutina que puse:
 

Código: Seleccionar todo

ORG #6000
          ld hl,hello
          ;and a          ; borra el flag del carry (puede no ser necesario)
loop:     ld a,(hl)
          inc hl          ; podria ser inc l
          rra
          call #bb5a
          jr nc,loop
          ret
hello     db "Hello, World","!"+1

charset #20,#40:charset #21,#42:charset #22,#44:charset #23,#46:charset #24,#48:charset #25,#4a
charset #26,#4c:charset #27,#4e:charset #28,#50:charset #29,#52:charset #2a,#54:charset #2b,#56
charset #2c,#58:charset #2d,#5a:charset #2e,#5c:charset #2f,#5e:charset #30,#60:charset #31,#62
charset #32,#64:charset #33,#66:charset #34,#68:charset #35,#6a:charset #36,#6c:charset #37,#6e
charset #38,#70:charset #39,#72:charset #3a,#74:charset #3b,#76:charset #3c,#78:charset #3d,#7a
charset #3e,#7c:charset #3f,#7e:charset #40,#80:charset #41,#82:charset #42,#84:charset #43,#86
charset #44,#88:charset #45,#8a:charset #46,#8c:charset #47,#8e:charset #48,#90:charset #49,#92
charset #4a,#94:charset #4b,#96:charset #4c,#98:charset #4d,#9a:charset #4e,#9c:charset #4f,#9e
charset #50,#a0:charset #51,#a2:charset #52,#a4:charset #53,#a6:charset #54,#a8:charset #55,#aa
charset #56,#ac:charset #57,#ae:charset #58,#b0:charset #59,#b2:charset #5a,#b4:charset #5b,#b6
charset #5c,#b8:charset #5d,#ba:charset #5e,#bc:charset #5f,#be:charset #60,#c0:charset #61,#c2
charset #62,#c4:charset #63,#c6:charset #64,#c8:charset #65,#ca:charset #66,#cc:charset #67,#ce
charset #68,#d0:charset #69,#d2:charset #6a,#d4:charset #6b,#d6:charset #6c,#d8:charset #6d,#da
charset #6e,#dc:charset #6f,#de:charset #70,#e0:charset #71,#e2:charset #72,#e4:charset #73,#e6
charset #74,#e8:charset #75,#ea:charset #76,#ec:charset #77,#ee:charset #78,#f0:charset #79,#f2
charset #7a,#f4:charset #7b,#f6:charset #7c,#f8:charset #7d,#fa:charset #7e,#fc:charset #7f,#fe
Saludos.

Meta
Forero habitual
Forero habitual
Mensajes: 103
Registrado: Jue 04 Ene , 2018 9:36 am

Re: Snippets en Z80

Mensajepor Meta » Dom 25 Sep , 2022 7:19 pm

Exacto, por eso comento.. que venía a colación. ;) la rutina es TXT_OUTPUT (&bb5a)

Las directivas estas son para WINAPE, desconozco si funcionan en otros ensambladores, por las dudas, quién esté empezando a programar en ensamblador es mejor que use DB, aparte de la compatibilidad.

Lo que has hecho al final es un chorizo macho XDD creo que puedes resumirlo así:

CHARSET "A","z","A"+1

lo he explicado antes, traspasa todos los caracteres de "A" a "z" con un valor de +1, o lo que tu quieras.

Siempre que pongas una "A", una "B" o una "C" en una cadena será con un +1,

También es deseable que estén definidos al principio del script, por los errores y eso.

Urusergi
Forum Addict
Forum Addict
Mensajes: 381
Registrado: Sab 25 Feb , 2006 5:45 pm

Re: Snippets en Z80

Mensajepor Urusergi » Dom 25 Sep , 2022 9:28 pm

Lo que has hecho al final es un chorizo macho XDD creo que puedes resumirlo así:

CHARSET "A","z","A"+1

lo he explicado antes, traspasa todos los caracteres de "A" a "z" con un valor de +1, o lo que tu quieras.

Siempre que pongas una "A", una "B" o una "C" en una cadena será con un +1,

También es deseable que estén definidos al principio del script, por los errores y eso.
Te aseguro que le he dado mil vueltas y no hay otra manera :throw:
El problema es que la directiva 'charset' incrementa en 1 y para este caso hace falta que vaya de 2 en 2 (realmente multiplicado por 2, o sea números pares) y no he encontrado otra manera que hacerlo a lo bruto :oops:
 
Hace falta esto:
#20 -> #40
#21 -> #42
#22 -> #44
.....
y con tu ejemplo de uso de la directiva conseguimos esto:
#20 -> #40
#21 -> #41
#22 -> #42
.....

Avatar de Usuario
robcfg
Master of The Forum
Master of The Forum
Mensajes: 1311
Registrado: Jue 03 Abr , 2008 5:32 pm
Ubicación: Estocolmo
Contactar:

Re: Snippets en Z80

Mensajepor robcfg » Dom 25 Sep , 2022 9:51 pm

Y si en vez de añadir 0x80 para activar el bit mas alto, lo desplazas un bit hacia la izquierda?

Así siempre tienes números pares y te ofusca el texto igualmente.

Urusergi
Forum Addict
Forum Addict
Mensajes: 381
Registrado: Sab 25 Feb , 2006 5:45 pm

Re: Snippets en Z80

Mensajepor Urusergi » Dom 25 Sep , 2022 10:05 pm

Y si en vez de añadir 0x80 para activar el bit mas alto, lo desplazas un bit hacia la izquierda?

Así siempre tienes números pares y te ofusca el texto igualmente.
Hello Robert,

Eso es precisamente lo que estamos tratando, pasar del típico 'text',"o"+#80 a un 't'*2,"e"*2,"x"*2,'t"*2,'o'*2+1 pero evitando tener que poner todo el rato el *2 a cada carácter usando la directiva del winape 'charset', que permite darle un nuevo valor a cada código ascii, pero estamos viendo que esa directiva está un tanto limitada #-o

Con el tocho que he puesto arriba todos los textos se escriben tal cual y sólo hay que añadir un +1 al final de cada cadena.
 

Meta
Forero habitual
Forero habitual
Mensajes: 103
Registrado: Jue 04 Ene , 2018 9:36 am

Re: Snippets en Z80

Mensajepor Meta » Lun 26 Sep , 2022 1:47 am

una chapucilla, pero puede servir

let chr = #20
repeat 95
charset chr,chr*2
let chr = chr+1
rend

org #4000
db " 0123ABCDEFz"

Urusergi
Forum Addict
Forum Addict
Mensajes: 381
Registrado: Sab 25 Feb , 2006 5:45 pm

Re: Snippets en Z80

Mensajepor Urusergi » Lun 26 Sep , 2022 9:36 pm

Genial! muchas gracias @Meta \:D/ queda mucho más elegante que el tocho mío.

Ahora bien, para que alcance el símbolo máximo (&7F) le falta un repeat más (repeat 96) y por otro lado, si queremos que funcionen los códigos de control de los que hemos hablado antes habría que empezar con let chr = #00:

Código: Seleccionar todo

let chr = #00
repeat 128
charset chr,chr*2
let chr = chr+1
rend
Y me he dado cuenta de un detalle, hay tres códigos de control que no se pueden usar 'a full' con las dos terminaciones de cadena (+#80 y +#01) porque pueden necesitar parámetros de 8 bits, pero creo que no se utilizan demasiado. Puede ser un pequeño inconveniente :-k

Saludos.
 

Meta
Forero habitual
Forero habitual
Mensajes: 103
Registrado: Jue 04 Ene , 2018 9:36 am

Re: Snippets en Z80

Mensajepor Meta » Lun 26 Sep , 2022 10:43 pm

De nada Urusergi,

Calculé hasta la "z" y me daban 95, creo que el valor era #f4.

Con los códigos ya me pierdo, pero debería funcionar cualquiera.

La terminación debe ser +1 para que haga un carry al dividir:

loop
ld a,(hl)
rrca ;; dividir, hay carry?
ret c ;; entonces salir
(carácter o código normalizado)
call txt_output
inc hl
jr loop

por lo tanto, si multiplicas por 2 lo que sea fuera de rango lo debería "normalizar" también, no sé, quizá me equivoco. Tendría que mirarlo.

Saludos



EDIT:
lo anterior esta mal, tienes razón hay que usar RRA y pierdes un bit.
aparte que la rutina no estaba bien


Esta creo que es correcta

org #4000
ld hl,string
loop
ld a,(hl)
rra
call &bb5a
ret c
inc hl
jr loop

string
db #82,#82+1

Urusergi
Forum Addict
Forum Addict
Mensajes: 381
Registrado: Sab 25 Feb , 2006 5:45 pm

Re: Snippets en Z80

Mensajepor Urusergi » Mar 27 Sep , 2022 12:32 am

Un consejo :mf_graduate: dentro de los bucles hay que procurar evitar los RET condicionales porque son costosos. En tu ejemplo tenemos al final:
 

Código: Seleccionar todo

ret c
inc hl
jr loop
son 2us cada vez que pasamos por RET C + 3us por cada salto del JR incondicional, y 3us cuando RET C provoca el retorno.
 

Código: Seleccionar todo

jr nc,loop
ret
y aquí son unicamente 3us por cada salto JR condicional y una sola vez se produce un gasto de 2us del JR condicional que no salta + 3us del RET

Saludos.

Meta
Forero habitual
Forero habitual
Mensajes: 103
Registrado: Jue 04 Ene , 2018 9:36 am

Re: Snippets en Z80

Mensajepor Meta » Mar 27 Sep , 2022 9:08 am

Buenas

Ayer estaba bastante espeso, hice un copia pega de la otra para hacer pruebas y lo deje asín :lol: , pero sí, me dí cuenta después.. De todos modos la rutina del firmware es tan lenta que ni se iba a notar.

Conclusión:

Con la terminación de +1 "integrada" en el carácter hay que usar RRA, y pierdes ese bit porque hay que borrarlo en el proceso. Pero si usas terminaciones sin "integrar" se puede usar RRCA y tener los 8 bits disponibles a costa de tener todas las cadenas con un byte adicional. Mejor la primera opción desde luego. Tienes hasta #7f, más que de sobra y los códigos fuera de rango raros pues... que les den.

Así que nada, hemos optimizado un rutina 1 byte creo <XX . pero bueno ya tenemos ofuscamiento, en nuestras cadenas y dominamos el arte de mover un bit pa' cá y otro pa' yá.

Urusergi
Forum Addict
Forum Addict
Mensajes: 381
Registrado: Sab 25 Feb , 2006 5:45 pm

Re: Snippets en Z80

Mensajepor Urusergi » Mar 27 Sep , 2022 9:47 pm

De todos modos la rutina del firmware es tan lenta que ni se iba a notar.
Ya, me refería a cualquier rutina en general, no en este caso donde la llamada del firmware &bb5a es la que ralentiza.
Así que nada, hemos optimizado un rutina 1 byte creo <XX
No te creas que es poca cosa :mrgreen: rascar un byte es casi un milagro cuando se trata de una subrutina que ocupa solo 10 bytes

Saludos.

Meta
Forero habitual
Forero habitual
Mensajes: 103
Registrado: Jue 04 Ene , 2018 9:36 am

Re: Snippets en Z80

Mensajepor Meta » Mié 28 Sep , 2022 12:42 am

Tienes razón, hay que ser quisquilloso con el Amstrad, que no andamos muy sobraos que digamos...

trocoloco
Megaforero
Megaforero
Mensajes: 335
Registrado: Lun 16 Abr , 2007 11:02 am

Re: Snippets en Z80

Mensajepor trocoloco » Mié 28 Sep , 2022 8:33 pm

Desde luego que rizáis el rizo con el código, que forma de sacarle el jugo! :shock:
¿Todas estas rutinas, modificaciones y mejoras tan curradas no podrían meterse en un github a modo de repositorio de consulta ?

Meta
Forero habitual
Forero habitual
Mensajes: 103
Registrado: Jue 04 Ene , 2018 9:36 am

Re: Snippets en Z80

Mensajepor Meta » Jue 29 Sep , 2022 12:43 am

Hola trocoloco,
Yo no sé que decirte, aquí quien se pego la currada fue syx (sin menospreciar al resto), y de eso hace mucho tiempo. Creo que aún es factible revisar las páginas que hay o usar el buscador, pero a lo mejor a otras personas les parece bien.

Urusergi
Forum Addict
Forum Addict
Mensajes: 381
Registrado: Sab 25 Feb , 2006 5:45 pm

Re: Snippets en Z80

Mensajepor Urusergi » Dom 26 Mar , 2023 10:49 pm

Estaba yo 'aburrío' y me puse a ver los primeros snippets del gran Syx. Al llegar a la rutina de desbloqueo del asic...
 

Código: Seleccionar todo

; Desbloqueamos el Asic
desbloquea_asic
DI
LD HL,secuencia_desbloqueo_asic
LD B,#BC ; Puerto para desbloquear el Asic
LD A,17 ; Longitud de la cadena para desbloquear el Asic
bucle_desbloquea_asic
INC B
OUTI ; OUTI = DEC B + OUT (C),(HL) + INC HL
DEC A
JR NZ,bucle_desbloquea_asic
EI
RET

secuencia_desbloqueo_asic
DEFB #FF,#00,#FF,#77,#B3,#51,#A8,#D4,#62
DEFB #39,#9C,#46,#2B,#15,#8A,#CD,#EE
 
... me pregunto ¿no se podría usar el registro C como contador en vez de A? :-k ganaríamos 1 byte + 1us y A quedaría libre...
 

Código: Seleccionar todo

; Desbloqueamos el Asic
desbloquea_asic
DI
LD HL,secuencia_desbloqueo_asic
LD BC,#BC11 ; Puerto & Longitud de la cadena para desbloquear el Asic

bucle_desbloquea_asic
INC B
OUTI ; OUTI = DEC B + OUT (C),(HL) + INC HL
DEC C
JR NZ,bucle_desbloquea_asic
EI
RET

secuencia_desbloqueo_asic
DEFB #FF,#00,#FF,#77,#B3,#51,#A8,#D4,#62
DEFB #39,#9C,#46,#2B,#15,#8A,#CD,#EE
 
... así que decidí probarlo en el winape y funciona \:D/
 


¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro


La Comunidad Española
ESP Soft, juegos para tu CPC Foro de Amstrad CPC Todos los juegos para CPC en un CD Web dedicada al Amstrad CPC (utilidades) Información útil para el CPC (talleres) Selección de juegos de Amstrad CPC Mundo CPC Pree Play then any Key CPC Basic