Emulando 2 opcodes de Z80 de una sola vez.
Publicado: 22 Nov 2018, 23:36
Muy buenas,
El señor Peter McGavin fue el primero que desarrolló un emulador de Spectrum para Amiga 500 en color. Para conseguir la máxima velocidad posible en el 68000 a 7Mhz del Amiga ideó un sistema que generaba una tabla de 128K en la que se almacenaba la dirección de desplazamiento del salto a la rutina de emulación de cada opcode almacenado en la memoria emulada del Spectrum, bastante ingenioso y rápido pero el 68000 no da para mucho. En la documentación de su emulador detallaba una alternativa a su sistema propuesta por otra persona que se utiliza en el mejor (y tal vez único?) emulador de Spectrum para Sinclair QL y en el de Atari ST, que consiste en usar el byte del opcode a emular como parte de la dirección de salto a la rutina emuladora utilizando la tecnica de código automodificable, por lo que escribe el señor McGavin en la documentación de su emulador, intentó implementar este sistema, pero las pruebas de rendimiento no le convencieron y la descartó, tambien explica otra idea que consiste en leer 2 opcodes a emular de una sola vez y en lugar de tener una rutina de emulación para cada opcode, se usaria una rutina para cada una de las posibles combinaciones de 2 opcodes simultaneos, esto sería una enorme ventaja en cuanto a velocidad de emulación, pero presenta un gran problema de cantidad de código a escribir y memoria necesaria.
Pensandolo un poco me doy cuenta que muchas de las combinaciones de opcodes que no interfieren uno con el otro solo necesitarían una rutina para las 2 posibles combinaciones de si uno va primero u otro despues, por ejemplo, la siguientes secuencias se suelen usar bastante y solo necesitarian una rutina para las 2 posibilidades de cada una:
LD H,D
LD L,E
Esta pareja de instrucciones y todas las variantes que no interfieren solo necesitarian una unica rutina tanto si va una instruccione primero u otra despues.
En cambio con las secuencias de INC o DEC de 8 bits no tendriamos esa suerte aunque nos ahorrariamos calcular los FLAGS de la primera instrucción, ejemplo:
INC A < solo incrementariamos A e ignorariamos los FLAGS
INC B < incrementariamos B y solo aqui calculariamos los FLAGS.
En este caso si necesitamos 2 rutinas distintas, 1 cuando se incrementa A primero y otra cuando es B.
Luego tendriamos los casos en los que el segundo opcode no es una instruccion, si no un dato, por ejemplo:
LD A,N apareceria 256 veces en la tabla de direcciones (1 por cada posible valor de N) apuntando a su rutina de emulacion unica.
Yo personalmente lo veo factible, la unica duda que me asalta es si cabría en los 512K de un Amiga 500...
El señor Peter McGavin fue el primero que desarrolló un emulador de Spectrum para Amiga 500 en color. Para conseguir la máxima velocidad posible en el 68000 a 7Mhz del Amiga ideó un sistema que generaba una tabla de 128K en la que se almacenaba la dirección de desplazamiento del salto a la rutina de emulación de cada opcode almacenado en la memoria emulada del Spectrum, bastante ingenioso y rápido pero el 68000 no da para mucho. En la documentación de su emulador detallaba una alternativa a su sistema propuesta por otra persona que se utiliza en el mejor (y tal vez único?) emulador de Spectrum para Sinclair QL y en el de Atari ST, que consiste en usar el byte del opcode a emular como parte de la dirección de salto a la rutina emuladora utilizando la tecnica de código automodificable, por lo que escribe el señor McGavin en la documentación de su emulador, intentó implementar este sistema, pero las pruebas de rendimiento no le convencieron y la descartó, tambien explica otra idea que consiste en leer 2 opcodes a emular de una sola vez y en lugar de tener una rutina de emulación para cada opcode, se usaria una rutina para cada una de las posibles combinaciones de 2 opcodes simultaneos, esto sería una enorme ventaja en cuanto a velocidad de emulación, pero presenta un gran problema de cantidad de código a escribir y memoria necesaria.
Pensandolo un poco me doy cuenta que muchas de las combinaciones de opcodes que no interfieren uno con el otro solo necesitarían una rutina para las 2 posibles combinaciones de si uno va primero u otro despues, por ejemplo, la siguientes secuencias se suelen usar bastante y solo necesitarian una rutina para las 2 posibilidades de cada una:
LD H,D
LD L,E
Esta pareja de instrucciones y todas las variantes que no interfieren solo necesitarian una unica rutina tanto si va una instruccione primero u otra despues.
En cambio con las secuencias de INC o DEC de 8 bits no tendriamos esa suerte aunque nos ahorrariamos calcular los FLAGS de la primera instrucción, ejemplo:
INC A < solo incrementariamos A e ignorariamos los FLAGS
INC B < incrementariamos B y solo aqui calculariamos los FLAGS.
En este caso si necesitamos 2 rutinas distintas, 1 cuando se incrementa A primero y otra cuando es B.
Luego tendriamos los casos en los que el segundo opcode no es una instruccion, si no un dato, por ejemplo:
LD A,N apareceria 256 veces en la tabla de direcciones (1 por cada posible valor de N) apuntando a su rutina de emulacion unica.
Yo personalmente lo veo factible, la unica duda que me asalta es si cabría en los 512K de un Amiga 500...