Consultas técnicas ensamblador Z80 (para AGD)

Avatar de Usuario
pser1
Mensajes: 4094
Registrado: 08 Dic 2012 18:34
Agradecido : 1352 veces
Agradecimiento recibido: 1118 veces

Consultas técnicas ensamblador Z80 (para AGD)

Mensajepor pser1 » 05 Jul 2018 17:27

Hola compañeros,
como amenacé antes, me decido a abrir un 'hilo' para ir incorporando consultas sobre partes del código
del juego FOGGY que no entienda suficientemente como para poder convertirlas a código 6809

El primer tema para ir abriendo boca es el sonido. ¿Cómo no?
Os adjunto aquí tanto el listado en ensamblador del juego FOGGY completo para Z80
como un listado comentado de la parte que genera sonidos ...
En el próximo mensaje os explico mis dudas al respecto

saludos
pere
_FOGGY.zip
(44.04 KiB) Descargado 76 veces

TrazadoManualSonidoZX.zip
(2.05 KiB) Descargado 64 veces

Avatar de Usuario
pser1
Mensajes: 4094
Registrado: 08 Dic 2012 18:34
Agradecido : 1352 veces
Agradecimiento recibido: 1118 veces

Re: Consultas técnicas ensamblador Z80 (para AGD)

Mensajepor pser1 » 05 Jul 2018 17:36

En el mensaje anterior os he adjuntado en un solo documento el código generador de sonidos en ensamblador de Z-80 comentado tal
como lo descargué del grupo AGD, algunos comentarios los he modificado para aclararme mejor, otros los he añadido sobre la marcha

Como, a pesar de los comentarios, no me hago una idea clara de como funciona, veréis en la columna de la izquierda un 'trazado' manual
con los valores que adquieren los registros al ir ejecutando la rutina ...

Cosas que entiendo que deben (deberían) suceder:
- Hay que llamar a la rutina una vez para que se le ponga valor a la variable 'clock' o en vsync4 siempre serán diferentes y no se emitirá sonido
- Cuando se llama a la rutina para que emita un sonido debe cumplirse que clock tenga el valor de (23672) o no habrá sonido
Y no veo como lo hace el programa FOGGY ya que NO pone valor alguno a 'clock' antes de llamar a esta rutina
A menos de que sea llamada con valor cero cada 'frame' y por tanto se cumplan los requisitos que acabo de decir ... ojalá sea esto!

Entiendo que (23672) es el byte bajo del contador de cuadros (frames) que supongo irá a razón de uno cada 20mseg (50Hz -> = 0,02seg) PAL

Asumiendo que se haya enviado el valor 'bajo' (5) al altavoz lo mantendrá un número de veces (20 en el caso imaginado), tras lo cual
enviará el valor máximo (253) también 20 veces. Esto completaría un ciclo de señal en onda cuadrada pasando de cero a tope
Si ahora el contador (que tiene el mismo valor 20) no ha bajado a cero, se repite la historia enviando un valor bajo y luego uno alto, o sea que obtendríamos

Código: Seleccionar todo

(253) Alto           ----------          ----------          ----------
                     |         |         |         |         |         |
                     |         |         |         |         |         |
                     |         |         |         |         |         |
(005) Bajo ----------          ----------          ----------          ----------
           de 20 a 0 de 20 a 0 de 20 a 0 de 20 a 0 de 20 a 0 de 20 a 0 de 20 a 0
Contador =    20        19        18        17  ...    2         1         0     

En este caso la cifra 20 sería el número de ciclos que se habrían generado de una duración de 20 bucles vsync3 cada semiperíodo.
Me parece raro que la cifra "sndtyp" esté determinando al mismo tiempo el número de ciclos a emitir y la anchura de cada semiciclo.

Para elucubrar un poco un bucle comparador en 6809 podría ser
lda clock ; obtener valor anterior
Bucle1 cmpa ,x ; siendo x puntero a valor 'cambiante'
beq Bucle1

El bucle utilizaría: 5+3 = 8 ciclos de CPU
Si lo hacemos 20 veces (regalando los ciclos de otros controles) serán 160 digamos 200 ciclos
El reloj en Dragón va a 0,89Mhz así que esto nos daría: 200*1/0,89 MHz = 0,225 mseg x semiciclo
Realizado 20 veces (20 cambios de nivel) = 4,5 mseg
Con lo cual parece que hay tiempo de sobra dentro de los 20 mseg de un cuadro

Vaya latazo os estoy pegando, para variar ;-)
Estoy convencido de que algo se me está escapando.
Espero que alguno de vosotros mucho mas versado en Z-80 pueda aclararme los puntos que me están patinando -nb

Muchísimas gracias por anticipado -drinks
saludos
pere

BlackHole
Mensajes: 1669
Registrado: 03 Ago 2011 23:07
Ubicación: Aluche, Madrid
Agradecido : 29 veces
Agradecimiento recibido: 523 veces

Re: Consultas técnicas ensamblador Z80 (para AGD)

Mensajepor BlackHole » 05 Jul 2018 20:06

Este tema está relacionado más con cómo funciona el sonido en el ZX Spectrum 16/48K que con el procesador Z80 en sí. Tenemos que tener en cuenta que en los ordenadores Spectrum originales, el sonido venía de un zumbador piezoeléctrico que tenía únicamente 2 estados (supongo que electrónicamente serían 2 voltajes) y los sonidos se conseguían cambiando muy rápidamente entre ellos. El código de la ROM contiene una tabla de cuántos T-states debemos mantener cada estado para conseguir una determinada nota musical pura, lo que no quiere decir que en ensamblador podamos utilizar otros valores intermedios con fragmentos de tiempo mínimos, para conseguir hacer "efectos" especiales. Pero es eso, tú imagina simplemente que es un dispositivo biestado, con el que te comunicas a base de OUTs.

No tiene nada que ver con el sonido en los Spectrum a partir del 128K, que incorporan ya un chip independiente generador de ondas de 3 canales+ruido, con volumen y envolvente ADSR (Attack/Decay/Sustain/Release) que no tiene nada que ver con el proceso del zumbador antiguo, que se tomaba el 100% del tiempo de CPU al tener que controlar minuciosamente los bucles de tiempo para generar las frecuencias.

Claro, si lo quieres traducir al sistema que pueda llevar el Dragon, lo primero tendrás que saber exactamente cómo produce sonido el Dragon, algo que yo desconozco. Si lleva un copro independiente para sonido, todos los cálculos de los bucles del Z80 de poco te sirven seguirlos al pie de la letra, sin hacer una interpretación más abstracta del proceso.

Avatar de Usuario
pser1
Mensajes: 4094
Registrado: 08 Dic 2012 18:34
Agradecido : 1352 veces
Agradecimiento recibido: 1118 veces

Re: Consultas técnicas ensamblador Z80 (para AGD)

Mensajepor pser1 » 05 Jul 2018 20:21

BlackHole escribió:Este tema está relacionado más con cómo funciona el sonido en el ZX Spectrum 16/48K que con el procesador Z80 en sí. Tenemos que tener en cuenta que en los ordenadores Spectrum originales, el sonido venía de un zumbador piezoeléctrico que tenía únicamente 2 estados (supongo que electrónicamente serían 2 voltajes) y los sonidos se conseguían cambiando muy rápidamente entre ellos. El código de la ROM contiene una tabla de cuántos T-states debemos mantener cada estado para conseguir una determinada nota musical pura, lo que no quiere decir que en ensamblador podamos utilizar otros valores intermedios con fragmentos de tiempo mínimos, para conseguir hacer "efectos" especiales. Pero es eso, tú imagina simplemente que es un dispositivo biestado, con el que te comunicas a base de OUTs.
No tiene nada que ver con el sonido en los Spectrum a partir del 128K, que incorporan ya un chip independiente generador de ondas de 3 canales+ruido, con volumen y envolvente ADSR (Attack/Decay/Sustain/Release) que no tiene nada que ver con el proceso del zumbador antiguo, que se tomaba el 100% del tiempo de CPU al tener que controlar minuciosamente los bucles de tiempo para generar las frecuencias.
Claro, si lo quieres traducir al sistema que pueda llevar el Dragon, lo primero tendrás que saber exactamente cómo produce sonido el Dragon, algo que yo desconozco. Si lleva un copro independiente para sonido, todos los cálculos de los bucles del Z80 de poco te sirven seguirlos al pie de la letra, sin hacer una interpretación más abstracta del proceso.

Muchas gracias por la rápida respuesta y la aclaración técnica.
Verás el Dragón dispone de una salida DAC de 6 bits a la cual se le puede enviar cualquier valor comprendido entre 0 y 63, por lo que
puedes generar ondas con esta 'definición', no está restringido a 2 niveles o sea alto y bajo, pero puede funcionar así también!
Mi problema es que no veo claro que un solo valor (sndtyp) se emplee para determinar el periodo de la señal a emitir (bucle de
retardo una vez enviado un nivel) y además que determine el número de inversiones de dicho valor (semiperíodos) ...
a menos que esto sea lo que realmente deseara quien programó la rutina de sonido para el motor del AGD para Spectrum
saludos
pere

Avatar de Usuario
pser1
Mensajes: 4094
Registrado: 08 Dic 2012 18:34
Agradecido : 1352 veces
Agradecimiento recibido: 1118 veces

Re: Consultas técnicas ensamblador Z80 (para AGD)

Mensajepor pser1 » 05 Jul 2018 20:30

buff,
ha llovido mucho desde la conversión del Hobbit ...
Intentaré trazar la ejecución del FOGGY y ver valores de registros y variables del sistema a cada llamada a la rutina de sonido.
A ver si me aclaro de nuevo con el SpecEmu ... ya he olvidado como funciona a pesar de la cantidad de sesiones de trazado/depuración
que tuve que realizar :-(
A ver su puedo 'demostrarme' que se llama, a cada cuadro, dicha rutina lo cual garantizaría que se pueda emitir sonido cada vez que haga falta
Si detecto algo 'raro' o imprevisto os lo contaré

saludos
pere

Avatar de Usuario
pser1
Mensajes: 4094
Registrado: 08 Dic 2012 18:34
Agradecido : 1352 veces
Agradecimiento recibido: 1118 veces

Re: Consultas técnicas ensamblador Z80 (para AGD)

Mensajepor pser1 » 06 Jul 2018 11:11

Buenos dias a todos,
ayer probé a debugar el FOGGY utilizando el SpecEmu v2.8 como hice en tantas ocasiones con The Hobbit
Pero el tiempo ha pasado y he olvidado algunos puntos importantes sobre como utilizar el SpecEmu
Lo arranco y a continuación cargo el fichero FOGGY.TAP usando opción File/OpenFile. Adjunto .tap por si alguien lo quiere probar.
El program aarranca y se para en la pantalla de menú donde el usuario debe seleccionar teclado o tipo de Joystick
En este punto abro el Debugge pulsando tecla Escape y me aparecen las ventanas del debugger tal como las había configurado
cuando convertí el Hobbit. Veo la ventana de código, registros, area de memoria y breakpoints.
A´ñado un breakpoint en #7F5E que es la parte de código que empieza a tratar de sonido y quiero debugarlo paso a paso
o bien saltarlo y esperar a la próxima vez que sea llamado ... y ésto es lo que NO soy capaz de hacer :-(
Puedo seguir el programa paso a paso (Step / Next), pero Leave no devuelve control al programa para seleccionar 1 (teclado)
Y lo peor es que NO puedo cerrar el debugger ni el SpecEmu
Si alguien puede refrescarme la memoria o tiene un manual del mismo se lo agradeceré muchísmimo -drinks
En el zip adjunto he incluido el listado de la compilación que permite ver la posición en memoria del programa
saludos
pere
FOGGY.zip
(118.12 KiB) Descargado 80 veces

BlackHole
Mensajes: 1669
Registrado: 03 Ago 2011 23:07
Ubicación: Aluche, Madrid
Agradecido : 29 veces
Agradecimiento recibido: 523 veces

Re: Consultas técnicas ensamblador Z80 (para AGD)

Mensajepor BlackHole » 06 Jul 2018 11:31

Hola pser1,

Ayer solo aporté con prisas un pequeño comentario, porque tenía que irme. Acabo de venir de rehabilitación y ya tengo más o menos todo el día libre. He intentado echar un vistazo al código en TrazadoManualSonidoZX.zip, pero en su estado actual con todos los comentarios que has puesto a la izquierda, es bastante ilegible (por eso la gente pone los comentarios a la derecha tras los puntos y coma, hehehe) porque cada instrucción tiene una tabulación diferente y no me consigo aclarar. ¿Podrías pegarlo en su estado original, por favor?

De todas formas, creo que lo primero es necesario que sepas cómo funciona el puerto 254 en el Spectrum en modo salida, ya que solo 1 bit genera sonido, mientras que otros 3 cambian el color del borde, que tiene que mantenerse mientras se genera el sonido. Tienes una referencia en https://www.worldofspectrum.org/faq/reference/48kreference.htm#PortFE

Edito: Ya lo he recuperado yo en un editor de texto:

Código: Seleccionar todo

; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
vsync   ld a,(sndtyp)        ; sound to play
        and a                ; any sound?
        jp z,vsync1          ; no, Skip sound section
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        ld b,a               ; save A into B
        ld a,(23624)         ; get border colour (*8+attr lower half screen)
        rra                  ; divide
        rra                  ; by 8 to
        rra                  ; put border bits into b0-1-2
        ld c,a               ; save first value to send to speaker (border colour)
        ld a,b               ; restore received value
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        and a                ; test it
        jp m,vsync6          ; if negative, go play white noise
vsync2  ld a,c               ; get value to send to speaker
        out (254),a          ; write to speaker
        xor 248              ; toggle all except the border bits (b0-1-2)
        ld c,a               ; store value for next time
        ld d,b               ; store loop counter (received in A) into D
vsync3  ld hl,clock          ; get previous clock setting address
        ld a,(23672)         ; current clock setting (frame counter, incremented every 20 mseg)
        cp (hl)              ; subtract last reading
        jp nz,vsync4         ; if not equal skip next (exit loop)
        djnz vsync3          ; loopback
        ld b,d               ; restore loop counter
        djnz vsync2          ; continue noise
vsync4  ld a,d               ; get loop counter
vsynca  ld (sndtyp),a        ; save for next time

; synchronize to clock
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
vsync1  ld a,(23672)         ; get clock low byte
        rra                  ; rotate bit0 into carry
        call c,vsync5        ; if carry set,time to do shrapnel/ticker stuff
        ld hl,clock          ; get last clock reading address
vsync0  ld a,(23672)         ; get current clock reading
        cp (hl)              ; are they the same?
        jr z,vsync0          ; yes, wait until clock changes (20 mseg)
        ld (hl),a            ; set new clock reading into variable clock
        ret                  ; return
vsync5  call plsnd           ; play sound
vsync5  jp proshr            ; shrapnel and stuff

; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; Play white noise. A and B arrive both Negative with same value
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
vsync6  ld a,b               ; 128 - 255
        sub 127              ; 001 - 128
        ld b,a               ; pass value to B
        ld hl,clock          ; get previous clock setting address
vsync7  ld a,r               ; get random value
        and 248              ; retain only the speaker/earphone bits (b3-7)
        or c                 ; merge with border colour
        out (254),a          ; write to speaker
        ld a,(23672)         ; current clock setting
        cp (hl)              ; subtract last reading
        jp nz,vsync8         ; different, no more processing please
        ld a,b               ; restore received value
        and 127              ; reset bit7 (-> positive)
        inc a                ; to test
vsync9  dec a                ; for zero
        jr nz,vsync9         ; loopback if not zero
        djnz vsync7          ; continue noise
vsync8  xor a                ; A = zero
        jr vsynca            ; back to vsynca (no sound)
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; sndtyp        defb 0       ; maybe frequency? - can have these values:
;                            ; 20,35,40,45,50,60,70,80 (maybe others)
; clock defb 0               ; last clock reading.
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Una de las cosas que quizás tendrías que saber, es que en la posición 23672 ($5C78), el BASIC del Spectrum guarda un contador de 24 bits como variable del sistema FRAMES, que se incrementa una vez cada 1/50 segundos en la rutina de interrupción llamando a una rutina de la ROM situada en la posición 56 ($0038). Ese es el valor que creo que se compara con el contador "clock" definido en el programa. Ignoro si el AGD tiene las interrupciones del sistema habilitadas o tiene una rutina de interrupción propia, pero sea lo que sea, parece que el contador FRAMES se incrementa.

En la posición 23624 ($5C48) el Spectrum guarda otra variable del sistema BORDCR, que almacena en los bits 5/4/3 el color del borde, por eso tiene que rotarlos con RRA 3 veces hasta que queden en los bits 2/1/0, que son los esperados en el comando OUT para el puerto 254. El bit del sonido va a estar en el bit 4 de ese puerto, como ves el DAC solo tiene 1 bit de resolución, por eso tantísimo jaleo.

Otra característica del Spectrum que quizás no estés al tanto, es que la interrupción se ejecuta cada VBLANK (Vertical Blank), no pudiéndose lanzar en otra posición del barrido de pantalla como en Amstrad o Commodore 64. Por eso siempre va a haber una única interrupción cada cincuentavo de segundo (1/60 en los Spectrum americanos) si éstas están habilitadas.

Otra cosita: supongo que lo sabías, pero por tus comentarios del texto, me preguntaba si estás al tanto que la orden DJNZ lo que hace es decrementar el registro B y saltar si no ha llegado a cero.

Avatar de Usuario
pser1
Mensajes: 4094
Registrado: 08 Dic 2012 18:34
Agradecido : 1352 veces
Agradecimiento recibido: 1118 veces

Re: Consultas técnicas ensamblador Z80 (para AGD)

Mensajepor pser1 » 06 Jul 2018 13:31

BlackHole escribió:Hola pser1,
Ayer solo aporté con prisas un pequeño comentario, porque tenía que irme. Acabo de venir de rehabilitación y ya tengo más o menos todo el día libre. He intentado echar un vistazo al código en TrazadoManualSonidoZX.zip, pero en su estado actual con todos los comentarios que has puesto a la izquierda, es bastante ilegible (por eso la gente pone los comentarios a la derecha tras los puntos y coma, hehehe) porque cada instrucción tiene una tabulación diferente y no me consigo aclarar. ¿Podrías pegarlo en su estado original, por favor?

Bueno, los comentarios están *realmente* a la derecha del código.
Lo que ves a la izquierda es un trazado sobre papel linea a linea. Si te molesta para leer el código, no tienes mas que eliminarlo
con un editor de texto. Yo uso TextPad y marcando 'bloque' puedes eliminarlo fácilmente. NOTA: Veo que ya lo hiciste, perfecto!
De todas formas, creo que lo primero es necesario que sepas cómo funciona el puerto 254 en el Spectrum en modo salida, ya que solo 1 bit genera sonido, mientras que otros 3 cambian el color del borde, que tiene que mantenerse mientras se genera el sonido. Tienes una referencia en https://www.worldofspectrum.org/faq/reference/48kreference.htm#PortFE

Mas o menos lo entiendo, en el fondo lo que hace el generador de sonido es enviar un valor y luego aplicar un xor a los bits que no son del color del borde, por lo que va invirtiendo el nivel de salida, produciendo la forma de onda que indiqué en mi post. Gracias por el enlace!
Una de las cosas que quizás tendrías que saber, es que en la posición 23672 ($5C78), el BASIC del Spectrum guarda un contador de 24 bits como variable del sistema FRAMES, que se incrementa una vez cada 1/50 segundos en la rutina de interrupción llamando a una rutina de la ROM situada en la posición 56 ($0038). Ese es el valor que creo que se compara con el contador "clock" definido en el programa. Ignoro si el AGD tiene las interrupciones del sistema habilitadas o tiene una rutina de interrupción propia, pero sea lo que sea, parece que el contador FRAMES se incrementa.

Me pareció que se limita a comparar el contenido de la variable clock con el byte bajo del contador de frames.
Y al finalizar el sonido actualiza dicha variable
Creo que esto lo indiqué por un lado en los comentarios y además en el mensaje en el que pinté la forma de onda. Hasta aquí me parece claro.
Otra característica del Spectrum que quizás no estés al tanto, es que la interrupción se ejecuta cada VBLANK (Vertical Blank), no pudiéndose lanzar en otra posición del barrido de pantalla como en Amstrad o Commodore 64. Por eso siempre va a haber una única interrupción cada cincuentavo de segundo (1/60 en los Spectrum americanos) si éstas están habilitadas.

Exactamente igual que en Dragón donde podemos configurar si queremos la interrupción al inicio del frame o justo al final cuando empieza
el borrado vertical con lo que se trabaja 'fuera' de pantalla. Entiendo que en Spectrum es justo el segundo, o sea el borrado vertical.
De todas formas no he visto código relacionado con interrupciones o no he sabido verlo en FOGGY.
Por si acaso adjunté el fuente completo por si alguien puede o quiere echarle una ojeada mas a fondo ...
Muchas gracias por todo
pere

jltursan
Mensajes: 5619
Registrado: 20 Sep 2011 13:59
Ubicación: Madrid
Agradecido : 990 veces
Agradecimiento recibido: 2040 veces
Contactar:

Re: Consultas técnicas ensamblador Z80 (para AGD)

Mensajepor jltursan » 06 Jul 2018 15:09

Por defecto y si no me equivoco el ZX opera en IM1; así que si nadie redefine una interrupción IM2, así debe funcionar el juego.

Avatar de Usuario
pser1
Mensajes: 4094
Registrado: 08 Dic 2012 18:34
Agradecido : 1352 veces
Agradecimiento recibido: 1118 veces

Re: Consultas técnicas ensamblador Z80 (para AGD)

Mensajepor pser1 » 06 Jul 2018 15:20

jltursan escribió:Por defecto y si no me equivoco el ZX opera en IM1; así que si nadie redefine una interrupción IM2, así debe funcionar el juego.

O sea asumo que por defecto las interrupciones leen teclado, actualizan el contador de frames y algunas variables del sistema en IM1
Se parece al sistema por defecto en Dragón aunque no hace las mismas cosas (actualiza la variable TIMER)

muchas gracias
pere

Avatar de Usuario
pser1
Mensajes: 4094
Registrado: 08 Dic 2012 18:34
Agradecido : 1352 veces
Agradecimiento recibido: 1118 veces

Re: Consultas técnicas ensamblador Z80 (para AGD)

Mensajepor pser1 » 26 Jul 2018 20:17

NUEVO TEMA:
¿Podría alguien decirme que hacen exactamente estas líneas de código Z80 en el Spectrum 48k? -nb
ld a,71
and 7

No he encontrado información sobre un posible puerto 71 ($47) así que no tengo la mas remota idea
de que información recupera y que significan los tres bits mas bajos ...

Muchas gracias de antemano -drinks
pere

Avatar de Usuario
pser1
Mensajes: 4094
Registrado: 08 Dic 2012 18:34
Agradecido : 1352 veces
Agradecimiento recibido: 1118 veces

Re: Consultas técnicas ensamblador Z80 (para AGD)

Mensajepor pser1 » 26 Jul 2018 20:30

entiendo que simplemente le mete el valor decimal 71, pero para hacerle un AND luego
se habrían haber ahorrado un byte y hacer directamente
ld a,7
Si es otra cosa agradeceré me lo digáis
Muchas gracias
pere

Avatar de Usuario
explorer
Mensajes: 695
Registrado: 10 Ene 2016 18:43
Ubicación: Valladolid, España
Agradecido : 24 veces
Agradecimiento recibido: 680 veces
Contactar:

Re: Consultas técnicas ensamblador Z80 (para AGD)

Mensajepor explorer » 26 Jul 2018 20:41

En efecto, primero mete el valor 71 (0b01000111) en el acumulador y luego le hace un and con el valor 7 (0b00000111). El resultado es, desde luego, 7, pero... ¿por qué no lo hace en un solo paso?

Pues... no lo hace porque podría estar usando código automodificable.

Quiero decir que el valor 71 sigue al opcode de ld a,N. Si el código está en RAM, otra parte del código podría referirse a la dirección de memoria de ese valor 71, y cambiarlo. Entonces, cuando la CPU vuelva a ejecutar esa parte del código, el resultado del and será distinto.

Este tipo de trucos se usaba mucho en la época, para ahorrar memoria. En este caso, te ahorras tener un byte reservado aparte para almacenar una variable global. Usas el propio código del programa para guardar el valor.

Avatar de Usuario
pser1
Mensajes: 4094
Registrado: 08 Dic 2012 18:34
Agradecido : 1352 veces
Agradecimiento recibido: 1118 veces

Re: Consultas técnicas ensamblador Z80 (para AGD)

Mensajepor pser1 » 26 Jul 2018 20:47

explorer escribió:En efecto, primero mete el valor 71 (0b01000111) en el acumulador y luego le hace un and con el valor 7 (0b00000111). El resultado es, desde luego, 7, pero... ¿por qué no lo hace en un solo paso?
Pues... no lo hace porque podría estar usando código automodificable.
Quiero decir que el valor 71 sigue al opcode de ld a,N. Si el código está en RAM, otra parte del código podría referirse a la dirección de memoria de ese valor 71, y cambiarlo. Entonces, cuando la CPU vuelva a ejecutar esa parte del código, el resultado del and será distinto.
Este tipo de trucos se usaba mucho en la época, para ahorrar memoria. En este caso, te ahorras tener un byte reservado aparte para almacenar una variable global. Usas el propio código del programa para guardar el valor.

Muchísimas gracias, -drinks
me ha quedado clarísimo.
He revisado el código por si se utilizaba la etiqueta que precede al ld a,71 en alguna otra parte
y parece que no, así que voy a imaginar que al ser código creado automáticamente por el generador AGD
simplemente no es tan eficiente como sería deseable.
saludos
pere

Avatar de Usuario
explorer
Mensajes: 695
Registrado: 10 Ene 2016 18:43
Ubicación: Valladolid, España
Agradecido : 24 veces
Agradecimiento recibido: 680 veces
Contactar:

Re: Consultas técnicas ensamblador Z80 (para AGD)

Mensajepor explorer » 26 Jul 2018 21:31

La dirección del 71 debería ser "etiqueta+1", cuidado. Pero si es código generado... es muy probable que sea un fallo de optimización.

Avatar de Usuario
pser1
Mensajes: 4094
Registrado: 08 Dic 2012 18:34
Agradecido : 1352 veces
Agradecimiento recibido: 1118 veces

Re: Consultas técnicas ensamblador Z80 (para AGD)

Mensajepor pser1 » 26 Jul 2018 21:58

explorer escribió:La dirección del 71 debería ser "etiqueta+1", cuidado. Pero si es código generado... es muy probable que sea un fallo de optimización.

Tampoco existe ninguna referencia a etiqueta+1
Digamos que simplemente *no* se ha optimizado la salida del generador de código Z-80
Esta combinación de ld a,NN seguida de and 7 la he encontrado en bastantes partes del código
Y muchas veces *no* tiene ninguna etiqueta por las cercanías ...
Resulta ser el paso previo a llamar a la rutina que colorea los sprites.
El código que le pasan va en el registro A y solo admite 8 valores, de ahí el AND ...
Como en el 6809 no tendremos 'cambios' de colores en los sprites, de entrada, me he limitado a no
convertir el código de estas partes.
Muchas gracias -thumbup
saludos
pere


Volver a “Software Dragon”

¿Quién está conectado?

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