Primeros pasos para pogramar un emulador

Foro dedicado a la emulación de sistemas clásicos en el PC o en otros sistemas.
Avatar de Usuario
Namek
Atari 1040 STf
Atari 1040 STf
Mensajes: 838
Registrado: 11 Jul 2011, 13:13
Gracias dadas: 18 veces
Gracias recibidas: 63 veces

Re: Primeros pasos para pogramar un emulador

Mensajepor Namek » 06 Sep 2021, 00:42

Para que te hagas una idea yo empece a programar el emulador de Spectrum en AMOS con el Amiga 500 en 1991, solo el reset inicial tardaba casi 1 minuto, luego lo pase a BLITZ BASIC en el Amiga 1200 con la aceleradora 68060 y pasando mucho código a ensamblador por fin pude emular el Spectrum a velocidad real. Mas tarde hice versiones para PalmOS que también usaba una CPU compatible 680000 y para Atari ST. Y por ultimo y solo por entretenerme hice versiones para PC en FreeBASIC, Visual Basic 6 y JAVA y por ultimo para Android en JAVA.

ZX81
MSX Turbo R
MSX Turbo R
Mensajes: 487
Registrado: 20 Abr 2005, 19:18
Gracias dadas: 3 veces

Re: Primeros pasos para pogramar un emulador

Mensajepor ZX81 » 06 Sep 2021, 09:53

Namek escribió:Para que te hagas una idea yo empece a programar el emulador de Spectrum en AMOS con el Amiga 500 en 1991, solo el reset inicial tardaba casi 1 minuto, luego lo pase a BLITZ BASIC en el Amiga 1200 con la aceleradora 68060 y pasando mucho código a ensamblador por fin pude emular el Spectrum a velocidad real. Mas tarde hice versiones para PalmOS que también usaba una CPU compatible 680000 y para Atari ST. Y por ultimo y solo por entretenerme hice versiones para PC en FreeBASIC, Visual Basic 6 y JAVA y por ultimo para Android en JAVA.


Hola,
El emulador de Android lo tienes publicado en Play Store? Es para echarle un vistazo.

Saludos.
10 REM ESTA LINEA NO HACE NADA

ZX81
MSX Turbo R
MSX Turbo R
Mensajes: 487
Registrado: 20 Abr 2005, 19:18
Gracias dadas: 3 veces

Re: Primeros pasos para pogramar un emulador

Mensajepor ZX81 » 06 Sep 2021, 10:00

ZX-81 escribió:
ZX81 escribió:
Ahora sólo me quedaría buscar porque se cuelga el emulador en algunos programas, implementar el sonido (BEEPs) y añadir los t-states, porque todo va super rápido

Saludos.


Si quieres ver algo más, siempre puedes mirar el código de mi emulador, JSpeccy, que también está escrito en Java. En mis repos también tienes el código del core Z80 que gasta el emulador en Java y en C++, y que implementan una Z80 completa, con (casi) todos los bells & whistles.

Eso sí, te deseo buena suerte con él, si es que se te ocurre publicarlo. El 90% de la gente directamente odia Java, aunque no tienen ni idea de qué va la fiesta. Desde el 2011, me he encontrado con montones de personas que rajan del emulador sin siquiera haberlo probado.

Vamos, que si lo haces para aprender, cohonúo, pero como lo publiques, temo que te llevarás un chasco desagradable. Es lo que hay.


He visto que en tu emulador los T-States no los vas añadiendo en cada instrucción. Pones que en cada búsqueda de instrucción sumas 4 T-States, para cada lectura y escritura de memoria sumas 3 T-States y para cada IN y OUT sumas 4 T-States. Luego pones que en algunas instrucciones es necesario añadir algunos T-States más. Si no es mucha molestia, de qué instrucciones de tratarían?

Gracias.
10 REM ESTA LINEA NO HACE NADA

Avatar de Usuario
Namek
Atari 1040 STf
Atari 1040 STf
Mensajes: 838
Registrado: 11 Jul 2011, 13:13
Gracias dadas: 18 veces
Gracias recibidas: 63 veces

Re: Primeros pasos para pogramar un emulador

Mensajepor Namek » 06 Sep 2021, 10:51

ZX81 escribió:Hola,
El emulador de Android lo tienes publicado en Play Store? Es para echarle un vistazo.

Saludos.

No, lo hice en plan por probar, es básicamente lo mismo que la versión en JAVA que te mande pero adaptado a Android.

ZX81
MSX Turbo R
MSX Turbo R
Mensajes: 487
Registrado: 20 Abr 2005, 19:18
Gracias dadas: 3 veces

Re: Primeros pasos para pogramar un emulador

Mensajepor ZX81 » 06 Sep 2021, 19:03

ZX81 escribió:
ZX-81 escribió:
ZX81 escribió:
Ahora sólo me quedaría buscar porque se cuelga el emulador en algunos programas, implementar el sonido (BEEPs) y añadir los t-states, porque todo va super rápido

Saludos.


Si quieres ver algo más, siempre puedes mirar el código de mi emulador, JSpeccy, que también está escrito en Java. En mis repos también tienes el código del core Z80 que gasta el emulador en Java y en C++, y que implementan una Z80 completa, con (casi) todos los bells & whistles.

Eso sí, te deseo buena suerte con él, si es que se te ocurre publicarlo. El 90% de la gente directamente odia Java, aunque no tienen ni idea de qué va la fiesta. Desde el 2011, me he encontrado con montones de personas que rajan del emulador sin siquiera haberlo probado.

Vamos, que si lo haces para aprender, cohonúo, pero como lo publiques, temo que te llevarás un chasco desagradable. Es lo que hay.


He visto que en tu emulador los T-States no los vas añadiendo en cada instrucción. Pones que en cada búsqueda de instrucción sumas 4 T-States, para cada lectura y escritura de memoria sumas 3 T-States y para cada IN y OUT sumas 4 T-States. Luego pones que en algunas instrucciones es necesario añadir algunos T-States más. Si no es mucha molestia, de qué instrucciones de tratarían?

Gracias.


Bueno, al final estoy escribiendo los t-states instrucción a instrucción. ¿Sabéis de alguna web donde salgan los tiempos de los T- States con una fácil lectura para ir copiándolos? Ahora estoy utilizando esta web https://clrhome.org/table/ , pero es incomodísimo ir con el mouse a cada casilla para ver los tiempos. :?

Saludos.
10 REM ESTA LINEA NO HACE NADA

ZX-81
Amstrad PCW 8256
Amstrad PCW 8256
Mensajes: 128
Registrado: 04 Ene 2013, 16:43
Sistema Favorito: Spectrum +2
primer_sistema: ZX81
consola_favorita: Nintendo DS/3DS
Primera consola: Sega Genesis/Megadrive
Ubicación: La orilla del mar Mediterráneo
Gracias dadas: 16 veces
Gracias recibidas: 27 veces
Contactar:

Re: Primeros pasos para pogramar un emulador

Mensajepor ZX-81 » 06 Sep 2021, 21:31

ZX81 escribió:
ZX-81 escribió:
ZX81 escribió:
Ahora sólo me quedaría buscar porque se cuelga el emulador en algunos programas, implementar el sonido (BEEPs) y añadir los t-states, porque todo va super rápido

Saludos.


Si quieres ver algo más, siempre puedes mirar el código de mi emulador, JSpeccy, que también está escrito en Java. En mis repos también tienes el código del core Z80 que gasta el emulador en Java y en C++, y que implementan una Z80 completa, con (casi) todos los bells & whistles.

Eso sí, te deseo buena suerte con él, si es que se te ocurre publicarlo. El 90% de la gente directamente odia Java, aunque no tienen ni idea de qué va la fiesta. Desde el 2011, me he encontrado con montones de personas que rajan del emulador sin siquiera haberlo probado.

Vamos, que si lo haces para aprender, cohonúo, pero como lo publiques, temo que te llevarás un chasco desagradable. Es lo que hay.


He visto que en tu emulador los T-States no los vas añadiendo en cada instrucción. Pones que en cada búsqueda de instrucción sumas 4 T-States, para cada lectura y escritura de memoria sumas 3 T-States y para cada IN y OUT sumas 4 T-States. Luego pones que en algunas instrucciones es necesario añadir algunos T-States más. Si no es mucha molestia, de qué instrucciones de tratarían?

Gracias.


Efectivamente, no los añado instrucción a instrucción simplemente porque eso no vale para emular un Spectrum al 100%, ya que para emular la memoria en contienda necesitas que las cosas sucedan exactamente, o lo suficientemente cerca, a como las haría la CPU. En otros emuladores puedes tomarte "licencias" que aceleran la ejecución, pero no en el Spectrum. Por ejemplo, si te vas al Z80.java, línea 1935, tienes la instrucción DJNZ. Todas las instrucciones comienzan leyendo el opcode de RAM (3 ciclos) y luego un ciclo más de decodificación, durante el cual se pone el contenido del par IR en el bus de direcciones para que la RAM haga su refresco.

Pero en DJNZ hay un quinto ciclo más y ese se genra llamando al método addressOnBus. En cualquier otro ordenador eso no importaría mucho, pero en el Spectrum es fundamental. En la línea 1941 tienes otra llamada al mismo método que añade 5 ciclos durante los cuales la CPU real calcula la dirección del salto para DJNZ, pero mientras que en el primer caso lo que causará la contención será el contenido de IR, en el siguiente es el contenido del registro PC en ese preciso momento y ciclo a ciclo. Y cada uno de esos ciclos provocará una contención diferente, dependiendo de donde se encuentre.

Una optimización podría ser que solo leyera el byte de desplazamiento si B != 0, si no, añades a capón los 3 ciclos que costaría la lectura y no lees nada. De nuevo, con ese tipo de emulación no te sale un Spectrum ni de broma.

Por otro lado, estrictamente hablando, la CPU nada sabe de contar ciclos, para ella todos los ciclos son iguales, nunca está a principio de cuadro, ni al final, de modo que estructuralmente no me parece muy correcto que la CPU cuente nada. Mejor que lo haga una clase Clock, que además te puede avisar de eventos en determinados momentos.

Espero no liarte mucho. :)
Todo espacio de dimensión finita distinta de cero con producto interno tiene una base ortonormal. Tiene sentido, cuando no piensas sobre ello.
Profesor de Matemáticas U.C. Berkeley

Empieza a jugar sin tener que compilar: JSpeccy
Emulador bare-metal para la Raspberry PI 2/3: ZXBaremulator

ZX81
MSX Turbo R
MSX Turbo R
Mensajes: 487
Registrado: 20 Abr 2005, 19:18
Gracias dadas: 3 veces

Re: Primeros pasos para pogramar un emulador

Mensajepor ZX81 » 08 Sep 2021, 23:22

ZX-81 escribió:
ZX81 escribió:
ZX-81 escribió:
Si quieres ver algo más, siempre puedes mirar el código de mi emulador, JSpeccy, que también está escrito en Java. En mis repos también tienes el código del core Z80 que gasta el emulador en Java y en C++, y que implementan una Z80 completa, con (casi) todos los bells & whistles.

Eso sí, te deseo buena suerte con él, si es que se te ocurre publicarlo. El 90% de la gente directamente odia Java, aunque no tienen ni idea de qué va la fiesta. Desde el 2011, me he encontrado con montones de personas que rajan del emulador sin siquiera haberlo probado.

Vamos, que si lo haces para aprender, cohonúo, pero como lo publiques, temo que te llevarás un chasco desagradable. Es lo que hay.


He visto que en tu emulador los T-States no los vas añadiendo en cada instrucción. Pones que en cada búsqueda de instrucción sumas 4 T-States, para cada lectura y escritura de memoria sumas 3 T-States y para cada IN y OUT sumas 4 T-States. Luego pones que en algunas instrucciones es necesario añadir algunos T-States más. Si no es mucha molestia, de qué instrucciones de tratarían?

Gracias.


Efectivamente, no los añado instrucción a instrucción simplemente porque eso no vale para emular un Spectrum al 100%, ya que para emular la memoria en contienda necesitas que las cosas sucedan exactamente, o lo suficientemente cerca, a como las haría la CPU. En otros emuladores puedes tomarte "licencias" que aceleran la ejecución, pero no en el Spectrum. Por ejemplo, si te vas al Z80.java, línea 1935, tienes la instrucción DJNZ. Todas las instrucciones comienzan leyendo el opcode de RAM (3 ciclos) y luego un ciclo más de decodificación, durante el cual se pone el contenido del par IR en el bus de direcciones para que la RAM haga su refresco.

Pero en DJNZ hay un quinto ciclo más y ese se genra llamando al método addressOnBus. En cualquier otro ordenador eso no importaría mucho, pero en el Spectrum es fundamental. En la línea 1941 tienes otra llamada al mismo método que añade 5 ciclos durante los cuales la CPU real calcula la dirección del salto para DJNZ, pero mientras que en el primer caso lo que causará la contención será el contenido de IR, en el siguiente es el contenido del registro PC en ese preciso momento y ciclo a ciclo. Y cada uno de esos ciclos provocará una contención diferente, dependiendo de donde se encuentre.

Una optimización podría ser que solo leyera el byte de desplazamiento si B != 0, si no, añades a capón los 3 ciclos que costaría la lectura y no lees nada. De nuevo, con ese tipo de emulación no te sale un Spectrum ni de broma.

Por otro lado, estrictamente hablando, la CPU nada sabe de contar ciclos, para ella todos los ciclos son iguales, nunca está a principio de cuadro, ni al final, de modo que estructuralmente no me parece muy correcto que la CPU cuente nada. Mejor que lo haga una clase Clock, que además te puede avisar de eventos en determinados momentos.

Espero no liarte mucho. :)


Hola,
Gracias por la explicación. :) Al final he puesto todos los T-States instrucción a instrucción. He hecho una rutina para que cuente el tiempo que tardan en ejecutarse los 69888 T-States (creo que así lo hace el Spectaculator por lo que he visto), luego he añadido un retardo a partir del tiempo que han consumido los T-States, hasta llegar a los 20ms, actualizar pantalla, y así el emulador ya va a una velocidad más o menos correcta. :)

Saludos.
10 REM ESTA LINEA NO HACE NADA

ZX81
MSX Turbo R
MSX Turbo R
Mensajes: 487
Registrado: 20 Abr 2005, 19:18
Gracias dadas: 3 veces

Re: Primeros pasos para pogramar un emulador

Mensajepor ZX81 » 09 Sep 2021, 13:52

Hola,
Ahora estoy mirando como hacer el tema de los sonidos (BEEP) en el emulador, la verdad que no tengo ni idea como implemantarlos. :? Imagino que será ir guardando los todos OUTs en un array y cuando se cumplan los 69888 T-States enviarlos a alguna clase que gestione el tema de los sonidos. :? No sé si existe alguna clase de java estandard con la que se pueda hacer.
También me queda otra cosa pendiente, es el tema del BORDER, me explico, por ejemplo cuando hago un SAVE no se ven las típicas líneas que salen en la pantalla del Spectrum cuando está grabando, sólo se ven flases. Ni idea como solucionarlo. :(

Saludos.
10 REM ESTA LINEA NO HACE NADA

ZX-81
Amstrad PCW 8256
Amstrad PCW 8256
Mensajes: 128
Registrado: 04 Ene 2013, 16:43
Sistema Favorito: Spectrum +2
primer_sistema: ZX81
consola_favorita: Nintendo DS/3DS
Primera consola: Sega Genesis/Megadrive
Ubicación: La orilla del mar Mediterráneo
Gracias dadas: 16 veces
Gracias recibidas: 27 veces
Contactar:

Re: Primeros pasos para pogramar un emulador

Mensajepor ZX-81 » 09 Sep 2021, 14:15

ZX81 escribió:Hola,
Ahora estoy mirando como hacer el tema de los sonidos (BEEP) en el emulador, la verdad que no tengo ni idea como implemantarlos. :? Imagino que será ir guardando los todos OUTs en un array y cuando se cumplan los 69888 T-States enviarlos a alguna clase que gestione el tema de los sonidos. :? No sé si existe alguna clase de java estandard con la que se pueda hacer.
También me queda otra cosa pendiente, es el tema del BORDER, me explico, por ejemplo cuando hago un SAVE no se ven las típicas líneas que salen en la pantalla del Spectrum cuando está grabando, sólo se ven flases. Ni idea como solucionarlo. :(

Saludos.


Solo te digo que lo del BEEP es una de las cosas más xungas a las que me he enfrentado nunca, y cuando escribí JSpeccy llevaba más de 20 años viviendo de programar. Cada uno se imagina su manera de hacerlo, hay quien cuenta ciclos e intenta saber qué frecuencia debería generar para emularla. La mayor pega es que todo lo demás es emulado y puede pasar, pero el sonido es lo único que es tiempo real y como se te vacíe el buffer de sonido, para lo que Java tiene clases preparadas, enseguida empiezas a escuchar cosas que no deberían estar ahí.

Lo de los flashes del borde es porque estás debiendo actualizar la pantalla una vez por cuadro (error, por ejemplo, en el Arkanoid no verás la bola nunca) y durante la carga se cambia el color del borde múltiples veces. Ejecuta esto y mira qué pasa:

10 BORDER 2: BORDER 5: PAUSE 1: GOTO 10

Deberías ver como un tercio de la pantalla con borde rojo y luego azul, y si pulsas una tecla la frontera entre los colores cambia ligeramente. Si eso no lo emulas bien, no verás correctamente los juegos que hacen efectos con el borde, como Aquaplane o Beach Head II por poner dos ejemplos.

Y todavía te queda meterte con la memoria en contienda, el bus flotante,.... como escarpias se me ponen los pelos, oiga!. <XX
Todo espacio de dimensión finita distinta de cero con producto interno tiene una base ortonormal. Tiene sentido, cuando no piensas sobre ello.
Profesor de Matemáticas U.C. Berkeley

Empieza a jugar sin tener que compilar: JSpeccy
Emulador bare-metal para la Raspberry PI 2/3: ZXBaremulator

ZX81
MSX Turbo R
MSX Turbo R
Mensajes: 487
Registrado: 20 Abr 2005, 19:18
Gracias dadas: 3 veces

Re: Primeros pasos para pogramar un emulador

Mensajepor ZX81 » 09 Sep 2021, 14:25

ZX-81 escribió:
ZX81 escribió:Hola,
Ahora estoy mirando como hacer el tema de los sonidos (BEEP) en el emulador, la verdad que no tengo ni idea como implemantarlos. :? Imagino que será ir guardando los todos OUTs en un array y cuando se cumplan los 69888 T-States enviarlos a alguna clase que gestione el tema de los sonidos. :? No sé si existe alguna clase de java estandard con la que se pueda hacer.
También me queda otra cosa pendiente, es el tema del BORDER, me explico, por ejemplo cuando hago un SAVE no se ven las típicas líneas que salen en la pantalla del Spectrum cuando está grabando, sólo se ven flases. Ni idea como solucionarlo. :(

Saludos.


Solo te digo que lo del BEEP es una de las cosas más xungas a las que me he enfrentado nunca, y cuando escribí JSpeccy llevaba más de 20 años viviendo de programar. Cada uno se imagina su manera de hacerlo, hay quien cuenta ciclos e intenta saber qué frecuencia debería generar para emularla. La mayor pega es que todo lo demás es emulado y puede pasar, pero el sonido es lo único que es tiempo real y como se te vacíe el buffer de sonido, para lo que Java tiene clases preparadas, enseguida empiezas a escuchar cosas que no deberían estar ahí.

Lo de los flashes del borde es porque estás debiendo actualizar la pantalla una vez por cuadro (error, por ejemplo, en el Arkanoid no verás la bola nunca) y durante la carga se cambia el color del borde múltiples veces. Ejecuta esto y mira qué pasa:

10 BORDER 2: BORDER 5: PAUSE 1: GOTO 10

Deberías ver como un tercio de la pantalla con borde rojo y luego azul, y si pulsas una tecla la frontera entre los colores cambia ligeramente. Si eso no lo emulas bien, no verás correctamente los juegos que hacen efectos con el borde, como Aquaplane o Beach Head II por poner dos ejemplos.

Y todavía te queda meterte con la memoria en contienda, el bus flotante,.... como escarpias se me ponen los pelos, oiga!. <XX


Cuando llegue a casa, probaré lo del borde que comentas. La memoria en contienda puede ser que sea cuando la ULA y el Z80 intentan acceder a la vez a la memoria??? bus flotante, esto qué es??? :jumper:

Saludos.
10 REM ESTA LINEA NO HACE NADA


Volver a “Emuladores”

¿Quién está conectado?

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