Fecha actual Dom Ago 25, 2019 11:50 pm

Emulador de PC, VGA y el Resto de Periféricos

Programación de los componentes de hardware más específicos de la plataforma PC.


Usuarios leyendo este tema: Ninguno

Emulador de PC, VGA y el Resto de Periféricos

Notapor ~ » Sab Mar 02, 2013 4:55 am

Hace un tiempo, cerca de hace 6 meses, en el 2012, aproximadamente de Junio a Agosto, estuve trabajando en un emulador de VGA y CPU x86 como manera tanto de entender HTML5 como de llevar mi conocimiento a un lugar más accesible, tal como es el navegador.

Versión 0.1
Versión 0.2
Versión 0.3
Versión 0.4
Versión 0.5
Versión 0.6





La intención actual de crear este emulador de PC x86 es poder entender todo al más bajo nivel de hardware posible, para entender exactamente cómo funciona cada aspecto de la PC a nivel de hardware, y desde ahí ser capaces de correr cualquier programa de PC, aprendiendo así sobre el desarrollo de sistemas operativos a un nivel mucho más formal.

Entre otras cosas, he aprendido a capturar los eventos del teclado, las bases para leer y escribir archivos binarios usando las APIs de Firefox, usar Canvas y Typed Arrays, los inicios de las APIs de generación de audio (para crear un emulador de Speaker y de tarjeta de sonido a partir de APIs de generación de tonos, y sintetización de sonido, que es algo que debo aprender).

Si quiero que todo funcione de forma más fluida, tendría que usar Web Workers (en otras palabras, simples multihilos independientes).





Como se ve, hemos aprendido HTML5 (Web Workers, Web Audio o la antigua y obsoleta API de sonido de Firefox, Canvas), elementos de Low Level JavaScript (Typed Arrays) y de interacción con el usuario, así como acceso al sistema de archivos local, para hacer posible estudiar de forma efectiva temas relacionados a la programación de hardware, desarrollo de drivers, sistemas operativos y software de bajo nivel, y programación de algoritmos de alto nivel para profesionalizarnos.





Así que en lo que resta de este tema, vamos a comenzar un flujo de instrucciones humanas para estudiar todo lo que ya sabemos, una vez más, pero esta vez concretando todo lo estudiado en la forma de nuestro emulador, que debe ser capaz de ejecutar MS-DOS en modo de 16 bit puro, y luego, FreeDOS y cualquier otro código de 32 bits sin problemas.

Comenzaremos desde lo más urgente inmediatamente, implementando todos los trucos e información de hardware que encontremos con inmediatez (como los efectos de cada registro VGA y las instrucciones del CPU que necesitemos solo en ese momento, a medida las veamos por primera vez desde el boot, y luego desde nuestro propio BIOS, comenzando por las variedades de opcodes específicas a lo que vamos a usar).
Imagen
IP for hosts file (email udocproject@yahoo.com to get updates if website becomes offline):
Código: Seleccionar todo
190.150.9.244 archefire.org



See what I'm doing in real time:
Main Desktop 1
Main Desktop 2
Avatar de Usuario
~
Site Admin
 
Mensajes: 2958
Registrado: Sab Nov 10, 2012 1:04 pm

Re: Emulador de PC, VGA y el Resto de Periféricos

Notapor ~ » Dom Mar 03, 2013 6:34 am

Por ahora estoy acumulando nuevo código en el siguiente programa de HTML5:

VGAEmu, versión 2013-03-02





Por ahora solo he agregado código para poder manejar la instrucción xor dx,dx.

Veo que desde este punto necesito más disciplina, así que voy a comenzar a documentar esto en un SourceDoc formal para mi Emulador de PC Estándar (que es lo único que me separará de realmente poder fabricar una PC con hardware 100% estándar escalable, tal como cuando comenzaban las PCs, pero con características modernas, estandarizadas, y totalmente documentadas).
Avatar de Usuario
~
Site Admin
 
Mensajes: 2958
Registrado: Sab Nov 10, 2012 1:04 pm

Re: Emulador de PC, VGA y el Resto de Periféricos

Notapor ~ » Dom Mar 03, 2013 8:29 am

Sobre la emulación futura del mouse, tengo la idea de detectar cuándo se sale y se entra del área del Canvas, y cuando uno salga de esta, hacer que se detecte y se desactive la conexion entre el mouse y el controlador emulado.

Una vez que entremos nuevamente en el área del Canvas, debemos mostrar un icono de mouse para darnos la opción de dar clic en el área que más conveniente nos parezca del Canvas, para comenzar nuevamente la emulación del mouse en ese punto.
Imagen
IP for hosts file (email udocproject@yahoo.com to get updates if website becomes offline):
Código: Seleccionar todo
190.150.9.244 archefire.org



See what I'm doing in real time:
Main Desktop 1
Main Desktop 2
Avatar de Usuario
~
Site Admin
 
Mensajes: 2958
Registrado: Sab Nov 10, 2012 1:04 pm

Re: Emulador de PC, VGA y el Resto de Periféricos

Notapor ~ » Dom Mar 03, 2013 9:26 am

Mientras trato de descifrar una forma rutinaria de manejar el byte ModRM, me doy cuenta de que la programación no es más que la actividad de repetirle a la máquina, en código fuente, lo que la realidad nos dicta, y repetirlo para crear un reflejo espejo de esa realidad, en el ámbito de tantos niveles como dicha realidad se repita en diferentes variedades aplicadas a diferentes aspectos y niveles de abstracción.
Imagen
IP for hosts file (email udocproject@yahoo.com to get updates if website becomes offline):
Código: Seleccionar todo
190.150.9.244 archefire.org



See what I'm doing in real time:
Main Desktop 1
Main Desktop 2
Avatar de Usuario
~
Site Admin
 
Mensajes: 2958
Registrado: Sab Nov 10, 2012 1:04 pm

Re: Emulador de PC, VGA y el Resto de Periféricos

Notapor ~ » Lun Mar 04, 2013 7:47 am

Un detalle del que me di cuenta al correr este programa en Firefox y en Chrome, es que Chrome e Internet Explorer no soportan argumentos de funciones con valores predeterminados, pero Firefox sí, y es posible que esta característica sea parte de ECMAScript 6.

Por detalles como estos es que siempre prefiero usar características y sintaxis más al estilo de C, para que el programa sea más portable a otros lenguajes, y no propenso a estos detalles técnicos.

Así que lo siguiente no corre bien en Chrome, pero sí en Firefox (en otras palabras, es mejor no usarlo, tal como si usáramos la simplicidad de C):
Código: Seleccionar todo
function test(var1, var2=0xFFFF)
{
 alert("var2 "+var2);
}

test();


Javascript Functions and default parameters, not working in IE and Chrome

No deja de ser algo muy inesperado, especialmente de Chrome (que se supone que incluso tiene una implementación completa de HTML5), porque esto claramente puede dar problemas a mucho código existente.


Incluso PHP soporta valores de argumentos de función predeterminados:
Código: Seleccionar todo
 <?php
    function doFoo($Name = "Paul") {
        return "Foo $Name!\n";
    }

    doFoo();
    doFoo("Paul");
    doFoo("Andrew");
?>
Imagen
IP for hosts file (email udocproject@yahoo.com to get updates if website becomes offline):
Código: Seleccionar todo
190.150.9.244 archefire.org



See what I'm doing in real time:
Main Desktop 1
Main Desktop 2
Avatar de Usuario
~
Site Admin
 
Mensajes: 2958
Registrado: Sab Nov 10, 2012 1:04 pm

Re: Emulador de PC, VGA y el Resto de Periféricos

Notapor ~ » Lun Mar 04, 2013 7:48 am

Un detalle del que me di cuenta al correr este programa en Firefox y en Chrome, es que Chrome e Internet Explorer no soportan argumentos de funciones con valores predeterminados, pero Firefox sí, y es posible que esta característica sea parte de ECMAScript 6.

Por detalles como estos es que siempre prefiero usar características y sintaxis más al estilo de C, para que el programa sea más portable a otros lenguajes, y no propenso a estos detalles técnicos.

Así que lo siguiente no corre bien en Chrome, pero sí en Firefox (en otras palabras, es mejor no usarlo, tal como si usáramos la simplicidad de C):
Código: Seleccionar todo
function test(var1, var2=0xFFFF)
{
 alert("var2 "+var2);
}

test();


Javascript Functions and default parameters, not working in IE and Chrome

No deja de ser algo muy inesperado, especialmente de Chrome (que se supone que incluso tiene una implementación completa de HTML5), porque esto claramente puede dar problemas a mucho código existente.


Incluso PHP soporta valores de argumentos de función predeterminados:
Código: Seleccionar todo
 <?php
    function doFoo($Name = "Paul") {
        return "Foo $Name!\n";
    }

    doFoo();
    doFoo("Paul");
    doFoo("Andrew");
?>
Imagen
IP for hosts file (email udocproject@yahoo.com to get updates if website becomes offline):
Código: Seleccionar todo
190.150.9.244 archefire.org



See what I'm doing in real time:
Main Desktop 1
Main Desktop 2
Avatar de Usuario
~
Site Admin
 
Mensajes: 2958
Registrado: Sab Nov 10, 2012 1:04 pm

Re: Emulador de PC, VGA y el Resto de Periféricos

Notapor ~ » Mar Mar 12, 2013 8:26 pm

Quiero usar imágenes de floppy de 1.44 Megabytes, pero esos son demasiados datos.

Así que pienso comprimirlos con PHP, con un código como el siguiente:

Código: Seleccionar todo
<?php


function print_gzipped_output($filez="LowEST_Kern.img")
{
    $HTTP_ACCEPT_ENCODING = $_SERVER["HTTP_ACCEPT_ENCODING"];
    if( headers_sent() )
        $encoding = false;
    else if( strpos($HTTP_ACCEPT_ENCODING, 'x-gzip') !== false )
        $encoding = 'x-gzip';
    else if( strpos($HTTP_ACCEPT_ENCODING,'gzip') !== false )
        $encoding = 'gzip';
    else
        $encoding = false;
//print "afds";   
    if( $encoding )
    {
//        $contents = ob_get_clean();
        $contents=file_get_contents("LowEST_Kern.img");
        $_temp1 = strlen($contents);
        if ($_temp1 < 2048)    // no need to waste resources in compressing very little data
            print($contents);
        else
        {
            header('Content-Type: application/octet-stream');
            header('Content-Encoding: '.$encoding);
            print("\x1f\x8b\x08\x00\x00\x00\x00\x00");
            $contents = gzcompress($contents, 9);
            $contents = substr($contents, 0, $_temp1);
            header('Content-Length: '.strlen($contents));
            print($contents);
        }
    }
    else
        print(file_get_contents("LowEST_Kern.img"));
}





print_gzipped_output();
?>


Con esto, una imagen de floppy casi vacía puede pasar de 1.44 Megabytes a solo unos 13.5 Kilobytes.

Esto necesito integrarlo al XMLHttpRequest que lee datos de floppy en el emulador.

Otro truco más, de PHP, globalmente útil para muchas otras cosas, que vamos a usar para este proyecto.

Y la compresión GZIP no la tengo activada globalmente en el servidor porque así no puedo ver mi sitio desde mis Palm LifreDrive, así que voy a usar compresión solo para aplicaciones especiales como esta, que de todas formas no pueden correr en la Palm (no hay HTML5 ahí).






Para modo de 32 bits necesitamos una nueva versión del byte Mod/RM y el nuevo byte SIB.

Las cosas se vuelven difíciles porque se pueden usar instrucciones de 32 bits en código de 16 bits, e instrucciones de 16 bits en código de 32 bits.

Así que es difícil pensar cómo implementar esa funcionalidad sin duplicar código, y que sea usable globalmente por todas las instrucciones.

Las tablas que usamos son las siguientes (de los manuales de Intel):

Codificación de Direcciones de 16 Bits con Byte ModRM


Codificación de Direcciones de 16 Bits con Byte ModRM


Codificación de Direcciones de 16 Bits con Byte SIB



Este es el código capaz de generar opcodes para todos estos casos. Pero igual que con la tabla para 16 bits, direccionar los registros en orden de acuerdo a los diferentes casos de la tabla (registros generales, MMX o XMM), o una ubicación de memoria, requiere un poco más de código.

Eso sé cómo hacerlo en la mayor parte. Lo que no sé es concretamente, cómo recuperar la instrucción con todo y sus prefijos, y llamar la funcionalidad particular de cada instrucción a través de una función que interprete los bytes Mod/RM y SIB, y les pase los operadores.

Creo que antes de esto, sería necesario crear un desensamblador para cada instrucción, y así distinguir si nuestro código está siendo capaz de descifrar las instrucciones.

Así que creo que ese va a ser el siguiente paso: Crear un desensamblador comenzando con las instrucciones XOR, como prueba de concepto.


Código: Seleccionar todo
function modrmwords(modrm)
{
       if(mod(modrm)==1)
       {
        return "0";
       }


       if(mod(modrm)==2)
       {
        return "0,0,0,0";
       }

 return "";
}









function xor_32()
{
    var str="bits 32\n\n";
    for(var modrm=0; modrm<256; modrm++)
    {
     if(mod(modrm)<=2)
     {
       if(mod(modrm)==0 && rm(modrm)==5)
       {
        str+="db 0x31,"+modrm+",0,0,0,0\n";
        continue;
       }


           if(rm(modrm)==4)
           {
            for(var sib=0; sib<256; sib++)
            {
             var sibstr=SIB32(modrm, sib);
             if(sibstr!="")
             {
              str+="db 0x31,"+modrm+","+sibstr+"\n";
             }
            }

            continue;
           }
            else
            {
              str+="db 0x31,"+modrm;
            }


           var modrmstr=modrmwords(modrm);
           if(modrmstr!="")
           str+=","+modrmstr+"\n";

           else
           str+="\n";





      continue;
     }







     //If we are here, the Mod field is 3:
     ///
//     if(mod(modrm)==3)
//     {
//      str+="db 0x31,"+modrm+"\n";
      str+="\n";
//     }
    }

 return str;
}





function SIB32(modrm, sib)
{
 if(base(sib)==5)
 {
  if(mod(modrm)==0)
    return sib+",9,9,9,9";
  if(mod(modrm)==1)
    return sib+",8";
  if(mod(modrm)==2)
    return sib+",32,32,32,32";
 }

// if(index(sib)!=4)
 {
  return sib+","+modrmwords(modrm);
 }

 return "";
}








Estoy reuniendo y depurando el repositorio final de definiciones de valores de registros VGA.

Por ahora tengo los registros para el modo 320x200x256 colores, 640x480x16 colores, y 320x240x256 colores (Mode X).

Al principio tuve problemas en depurar el modo 640x480x16 colores, pero ahora los valores de registros son coherentes con el resto de referencias, y el video funciona bien.

Esta es una captura de pantalla rápida que muestra que el modo Gráfico VGA 640x480x16 colores ahora lo hemos depurado y ya funciona correctamente, al entrar a este sin usar el BIOS:

_

Para ver las definiciones en código fuente, ir aquí:

Definición Concisa de Registros VGA


Lo que nos interesa para esto es la sección Configuración de Registros para Modos de Video.

La "basura" que se veía anteriormente en la captura de pantalla es el contenido de la fuente en modo texto, que aparentemente comienza en la dirección 0xA0000, la misma en la que comienza la memoria de modo gráfico VGA estándar.

Principalmente hay un nevado de color café en la parte alta de la pantalla (la fuente de hardware corresponde al plano 2, contando los planos desde 0). Las líneas azul y verde son el contenido de los bytes de carácter y atributo de modo texto 80x25x16 colores (que corresponden a los planos 0 y 1 de la memoria de video), y como podemos ver, no llegan hasta el final de la pantalla aunque a la vez encajan bien en la resolución. Esto es porque ambos modos tienen 640 pixeles de anchura, pero el modo texto solo tiene 400 pixeles de altura en lugar de 480 y es por eso que se detiene ahí.

Pensándolo bien, esa demostración visual nos puede servir para calcular, dado el número de pixeles faltantes, el tamaño de cada plano de memoria (aunque se supone que cada plano tiene 65536, dado que la VGA estaba diseñada para funcionar con el procesador 8086 que tiene segmentos de 65536 bytes). Aunque claro, todo esto es una idea superficialmente concebida que necesita más meditación para que nos permita entender los planos de mucha mejor manera.

Esto también demuestra cómo se logra poner un logo y texto en la pantalla de inicio del BIOS. Es posible que para BIOSes que realmente usan modo gráfico y aun así son capaces de mostrar un logo, lo que hagan sea modificar algunos caracteres de la fuenta ASCII, desde los caracteres 128 a 255 como fragmentos del logo, y así logran estar en modo texto y mostrar por ejemplo el logo de Energy Star, etc., en modo de texto.

Ahora pongo aquí un índice que pienso rellenar con la información pertinente, que demuestra todo lo que necesitamos entender en principio para continuar con un emulador de VGA:

Guía de Programación a la EGA, VGA y Super VGA
Imagen
IP for hosts file (email udocproject@yahoo.com to get updates if website becomes offline):
Código: Seleccionar todo
190.150.9.244 archefire.org



See what I'm doing in real time:
Main Desktop 1
Main Desktop 2
Avatar de Usuario
~
Site Admin
 
Mensajes: 2958
Registrado: Sab Nov 10, 2012 1:04 pm

Re: Emulador de PC, VGA y el Resto de Periféricos

Notapor ~ » Vie Abr 12, 2013 3:12 pm

Este es un script que escribí en javascript para convertir un archivo de paleta de colores de 768 bytes usualmente (256 colores en grupos de 3 bytes RGB) a código fuente de Ensamblador:

PAL2src

Para quienes están más interesados en javascript aquí hay un truco.

Uno puede definir un link generado con javascript codificado en Base64, y también puede definir el nombre de archivo con la nueva propiedad download="nombre_de_archivo.exe".

Así que podemos tener un link de la forma:

Código: Seleccionar todo
<a href="data:application/octet-stream;base64,SG9sYQ==" download="Prueba.txt">Descargar archivo generado</a>



Y esto descargaría un archivo llamado Prueba.txt que contiene Hola.

Aquí usamos este truco para generar el código fuente y descargarlo automáticamente al dar clic al link generado, ya con un nombre de archivo de código fuente de Ensamblador adecuado:

PAL2src


Código: Seleccionar todo
<body bgcolor="#aaaaaa">

<pre id="a1">

</pre>


<script>

var file1="PALETTE_80x25x16.BIN";
var file2="PAL320x200x256.BIN";
var buff=new Array();
document.getElementById("a1").innerHTML="";

function genLink(idx, file)
{
 var xhr=new XMLHttpRequest();

 xhr.open("GET", file, true);
 xhr.responseType="arraybuffer";

 xhr.onload=function()
 {
  buff[idx]=new DataView(this.response);
  document.getElementById("a1").innerHTML+='<a href="data:application/octet-stream;base64,'+btoa(PAL2src(idx, file))+'" download="'+file+'.asm">'+file+".asm</a>\n";
 }

 xhr.send();
 return xhr;
}




function PAL2src(idx, file)
{
 var str=file.substring(0, file.indexOf("."))+":\r\n";
 for(var x=0; x<buff[idx].byteLength; x+=3)
 {
  str+="  Color_"+(x/3)+": db ";
  str+="0x"+buff[idx].getUint8(x).toString(16).toUpperCase()+",";
  str+="0x"+buff[idx].getUint8(x+1).toString(16).toUpperCase()+",";
  str+="0x"+buff[idx].getUint8(x+2).toString(16).toUpperCase()+"\r\n";
 }

 return str;
}



genLink(0, file1);
genLink(1, file2);


</script>
Imagen
IP for hosts file (email udocproject@yahoo.com to get updates if website becomes offline):
Código: Seleccionar todo
190.150.9.244 archefire.org



See what I'm doing in real time:
Main Desktop 1
Main Desktop 2
Avatar de Usuario
~
Site Admin
 
Mensajes: 2958
Registrado: Sab Nov 10, 2012 1:04 pm

Re: Emulador de PC, VGA y el Resto de Periféricos

Notapor ~ » Mar Abr 16, 2013 6:43 pm

Por ahora tengo dudas en cómo implementar las banderas OF, AF y CF del registro FLAGS.

El problema es que no sé si para OF es suficiente verificar que el bit de máximo peso de un valor cambie con respecto a su valor anterior.

Tampoco sé si para calcular AF es suficiente con verificar que el bit 4 (o tal vez los bits 4 a 7) tiene(n) un valor diferente al original.

Y tampoco sé si para calcular CF es suficiente hacer lo mismo que OF (verificar que el bit de máximo peso ha cambiado con respecto al valor original).
Imagen
IP for hosts file (email udocproject@yahoo.com to get updates if website becomes offline):
Código: Seleccionar todo
190.150.9.244 archefire.org



See what I'm doing in real time:
Main Desktop 1
Main Desktop 2
Avatar de Usuario
~
Site Admin
 
Mensajes: 2958
Registrado: Sab Nov 10, 2012 1:04 pm

Re: Emulador de PC, VGA y el Resto de Periféricos

Notapor ~ » Mar Abr 16, 2013 7:25 pm

La bandera ZF también ha llegado a darme dudas porque no sé ahora si, por ejemplo para un número de 8 bits, 0x80 y 0x00 van a activar la bandera ZF.

Esto es porque el manual de Intel dice: "La bandera ZF indica ya sea un cero con o sin signo".

Así que ahora tengo un trabajo más serio que hacer sobre aritmética binaria para asegurarme de entender, y de implementar de forma totalmente correcta estas banderas, en todos los casos.
Imagen
IP for hosts file (email udocproject@yahoo.com to get updates if website becomes offline):
Código: Seleccionar todo
190.150.9.244 archefire.org



See what I'm doing in real time:
Main Desktop 1
Main Desktop 2
Avatar de Usuario
~
Site Admin
 
Mensajes: 2958
Registrado: Sab Nov 10, 2012 1:04 pm

Re: Emulador de PC, VGA y el Resto de Periféricos

Notapor ~ » Mar Abr 16, 2013 11:50 pm

OF=0

FF-79 = 86

if value to add GREATER THAN (FF-79) then OF=1
Imagen
IP for hosts file (email udocproject@yahoo.com to get updates if website becomes offline):
Código: Seleccionar todo
190.150.9.244 archefire.org



See what I'm doing in real time:
Main Desktop 1
Main Desktop 2
Avatar de Usuario
~
Site Admin
 
Mensajes: 2958
Registrado: Sab Nov 10, 2012 1:04 pm

Re: Emulador de PC, VGA y el Resto de Periféricos

Notapor ~ » Mié Abr 17, 2013 1:45 pm

He encontrado un documento, el cual estoy traduciendo para entender hasta el más mínimo detalle de cómo manejar las banderas de acarreo (CF) y de desborde (OF):

La Bandera de Acarreo y la de Desborde en Aritmética Binaria


The CARRY flag and OVERFLOW flag in binary arithmetic
Imagen
IP for hosts file (email udocproject@yahoo.com to get updates if website becomes offline):
Código: Seleccionar todo
190.150.9.244 archefire.org



See what I'm doing in real time:
Main Desktop 1
Main Desktop 2
Avatar de Usuario
~
Site Admin
 
Mensajes: 2958
Registrado: Sab Nov 10, 2012 1:04 pm

Re: Emulador de PC, VGA y el Resto de Periféricos

Notapor ~ » Jue Abr 18, 2013 12:39 pm

Tengo este código de Ensamblador x86 de 16 bits bajo DOS, como una de muchas evaluaciones de las banderas:

Código: Seleccionar todo
;Esta instrucción prueba sumarle 1
;a un registro con valor de 0xFFFF para evaluar
;cómo se manejan las banderas, especialmente
;la de acarreo, de desborde, de acarreo auxiliar,
;y de signo.
;;

org 100h

mov ax,0xFFFF
add ax,1

int 20h



Para ADD:


OF=0
SF=0
ZF=1
AF=1
CF=1
PF=1


Banderas DEBUG a Banderas x86
Imagen
IP for hosts file (email udocproject@yahoo.com to get updates if website becomes offline):
Código: Seleccionar todo
190.150.9.244 archefire.org



See what I'm doing in real time:
Main Desktop 1
Main Desktop 2
Avatar de Usuario
~
Site Admin
 
Mensajes: 2958
Registrado: Sab Nov 10, 2012 1:04 pm

Re: Emulador de PC, VGA y el Resto de Periféricos

Notapor ~ » Jue Abr 18, 2013 4:32 pm

Después de darle una leída rápida al documento sobre la bandera de acarreo y la de desborde, veo que la forma más simple para calcular cada caso, es este:

Para la bandera de desborde, podemos usar este algoritmo para sumas y restas:
Código: Seleccionar todo
function calcular_desborde(Num1, Num2, Resultado)
{
 Signo_Num1=Preservar_solo_signo_con_AND_(Num1);
 Signo_Num2=Preservar_solo_signo_con_AND_(Num2);
 Signo_Resultado=Preservar_solo_signo_con_AND_(Resultado);

 //Limpiamos la bandera para inicializarla
 //correctamente:
 ///
  desactivar_bandera_desborde();

 if( (Signo_Num1 == Signo_Num2) && Signo_Resultado!=Signo_Num1 )
 {
  activar_bandera_desborde();
 }

 return bandera_desborde;
}




Para la bandera de acarreo cuando sumamos (donde acarreamos):
Código: Seleccionar todo
function calcular_acarreo_suma(Num1, Resultado)
{
 Signo_Num1=Preservar_solo_signo_con_AND_(Num1);
 Signo_Resultado=Preservar_solo_signo_con_AND_(Resultado);

 //Limpiamos la bandera para inicializarla
 //correctamente:
 ///
  desactivar_bandera_acarreo();


 if( Signo_Num1!=0 && Signo_Resultado==0 )
 {
  activar_bandera_acarreo();
 }

 return bandera_acarreo;
}




Para la bandera de acarreo cuando restamos (donde prestamos):
Código: Seleccionar todo
function calcular_acarreo_resta(Num1, Resultado)
{
 Signo_Num1=Preservar_solo_signo_con_AND_(Num1);
 Signo_Resultado=Preservar_solo_signo_con_AND_(Resultado);

 //Limpiamos la bandera para inicializarla
 //correctamente:
 ///
  desactivar_bandera_acarreo();


 if( Signo_Num1==0 && Signo_Resultado!=0 )
 {
  activar_bandera_acarreo();
 }

 return bandera_acarreo;
}

Imagen
IP for hosts file (email udocproject@yahoo.com to get updates if website becomes offline):
Código: Seleccionar todo
190.150.9.244 archefire.org



See what I'm doing in real time:
Main Desktop 1
Main Desktop 2
Avatar de Usuario
~
Site Admin
 
Mensajes: 2958
Registrado: Sab Nov 10, 2012 1:04 pm

Re: Emulador de PC, VGA y el Resto de Periféricos

Notapor ~ » Vie Abr 19, 2013 1:36 pm

Reflexionando sobre el estado de las banderas OF, CF y AF para XOR, ahora veo que OF y CF (desborde y acarreo) se ponen a cero porque no es posible causar desborde ni acarreo con una operación puramente binaria de bits (bitwise). Y ya que la bandera AF (acarreo auxiliar) se usa para el bit 3 de los primeros 8 bits de un valor de cualquier tamaño en lugar del bit de máximo peso como la bandera CF, y dado que esta se usa para interpretar valores como números BCD, se decidió dejar la bandera AF en un estado indefinido en lugar de 0 (tal vez la instrucción se diseñó por completo en compuertas antes de implementar números BCD, o alguna razón similar para no definir la bandera AF).
Imagen
IP for hosts file (email udocproject@yahoo.com to get updates if website becomes offline):
Código: Seleccionar todo
190.150.9.244 archefire.org



See what I'm doing in real time:
Main Desktop 1
Main Desktop 2
Avatar de Usuario
~
Site Admin
 
Mensajes: 2958
Registrado: Sab Nov 10, 2012 1:04 pm

Re: Emulador de PC, VGA y el Resto de Periféricos

Notapor ~ » Lun Abr 22, 2013 2:32 pm

Código: Seleccionar todo
;Este programa prueba la instrucción
;CMP con un valor de 0x48-0x00, 0xFF-0xFE,
;entre otros, para determinar si nuestra
;implementación concuerda con la ejecución real.
;;

org 100h

;Para 0x48-0x00 (0x48), las banderas deberían ser:
;  NV UP EI PL NZ NA PE NC
;;
 mov al,0x48
 cmp al,0


;Para 0xFF-0xFE (0x??), las banderas deberían ser:
;  NV UP EI PL NZ NA PO NC
;;
 mov al,0xFF
 cmp al,0xFE

int 20h
Imagen
IP for hosts file (email udocproject@yahoo.com to get updates if website becomes offline):
Código: Seleccionar todo
190.150.9.244 archefire.org



See what I'm doing in real time:
Main Desktop 1
Main Desktop 2
Avatar de Usuario
~
Site Admin
 
Mensajes: 2958
Registrado: Sab Nov 10, 2012 1:04 pm

Re: Emulador de PC, VGA y el Resto de Periféricos

Notapor ~ » Mar Abr 23, 2013 11:49 am

Código: Seleccionar todo
;Este programa prueba la instrucción
;DEC entre 0-1 para determinar el signo usado
;por el 1, si es 1 o -1.
;
;Si asumimos que 0 y 1 son positivos y el
;resultado -1 siendo negativo, produce la
;activación de la bandera de acarreo,
;consideraremos que el 1 usado por la instrucción
;DEC es positivo; de lo contrario consideraremos
;que es una suma de un negativo.
;;

org 100h

mov al,0
dec al


int 20h



Aarentemente, la instrucción DEC usa la suma de un negativo, así que usa -1 como segundo número implícito; y la instrucción INC usa la suma de un positivo, así que usa 1 como segundo número implícito.

La instrucción DEC solamente puede producir desborde si se aplica al valor 127 (0x7F, 0x7FFF o 0x7FFFFFFF). La instrucción INC solamente puede producir desborde si se aplica al valor -128 (0x80, 0x8000 o 0x80000000).

En cualquier caso, dado que siempre se pasa un resultado perfectamente lógico, perfectamente coherente, a la función que calcula la bandera OF, el resultado es correcto.

Y aparentemente es siempre mejor usar números binarios considerados sin signo a la hora de calcular la bandera de desborde, siempre sumando un número que represenaría un positivo, o sumando un número que representaría un negativo.
Imagen
IP for hosts file (email udocproject@yahoo.com to get updates if website becomes offline):
Código: Seleccionar todo
190.150.9.244 archefire.org



See what I'm doing in real time:
Main Desktop 1
Main Desktop 2
Avatar de Usuario
~
Site Admin
 
Mensajes: 2958
Registrado: Sab Nov 10, 2012 1:04 pm

Re: Emulador de PC, VGA y el Resto de Periféricos

Notapor ~ » Sab May 04, 2013 2:47 pm

Después de todo este tiempo, he logrado decidir qué cosas deberían haber sido las primeras en implementar para nuestra emulación.

Actualmente he implementado nuevamente el CPU actualmente con unas 50 instrucciones de la 8086 (modo de 16 bits puro de una 386).

Aquí está el emulador actual corriendo (se puede tardar unos segundos en descargar la imagen actual de BIOS provisional, incluida en el código fuente):

Emulador de PC Pre-Alpha en HTML5
snap


Código: Seleccionar todo
Z86Emu Version 2013-04-23; 0001

RAX=B800
RCX=0000
RDX=0000
RBX=0000
RSP=0500
RBP=0000
RSI=0011
RDI=0000

RIP=002B

ES=F000
CS=F000
DS=F000
SS=0000
FS=0000
GS=0000

;_eflags_
         dd 00000000000000000000000001000110b
;                     |||||| ||||||||| | | |
;                     |||||| ||||||||| | | |___ (00)Carry Flag                (CF)  -- STATUS
;                     |||||| ||||||||| | |_____ (02)Parity Flag               (PF)  -- STATUS
;                     |||||| ||||||||| |_______ (04)Auxiliary Carry Flag      (AF)  -- STATUS
;                     |||||| |||||||||_________ (06)Zero Flag                 (ZF)  -- STATUS
;                     |||||| ||||||||__________ (07)Sign Flag                 (SF)  -- STATUS
;                     |||||| |||||||___________ (08)Trap Flag                 (TF)  -- SYSTEM
;                     |||||| ||||||____________ (09)Interrupt Enable Flag     (IF)  -- SYSTEM
;                     |||||| |||||_____________ (10)Direction Flag            (DF)  -- CONTROL
;                     |||||| ||||______________ (11)Overflow Flag             (OF)  -- SYSTEM
;                     |||||| |++------------(12)(13)I/O Privilege Level     (IOPL)  -- SYSTEM
;                     |||||| |_________________ (14)Nested Task               (NT)  -- SYSTEM
;                     ||||||___________________ (16)Resume Flag               (RF)  -- SYSTEM
;                     |||||____________________ (17)Virtual-8086 Mode         (VM)  -- SYSTEM
;                     ||||_____________________ (18)Alignment Check           (AC)  -- SYSTEM
;                     |||______________________ (19)Virtual Interrupt Flag    (VIF) -- SYSTEM
;                     ||_______________________ (20)Virtual Interrupt Pending (VIP) -- SYSTEM
;                     |________________________ (21)ID Flag                   (ID)  -- SYSTEM




Para evaluar el código actual (en el Dominio Público), descargar este archivo:

ICON Z86Emu_PreAlpha_2013-05-04.zip

Lo Que Queda por Hacer


A diferencia de las versiones Pre-Alpha anteriores que había puesto aquí, desde esta versión particular del emulador, se ha implementado toda una infraestructura formal que permite capturar los puertos de Entrada/Salida, y regiones de memoria (de video, de otros periféricos, etc.), y manejarlas tanto a nivel lógico como de datos de dichos puertos.

Como se ve en la emulación, podemos manejar la memoria VGA, pero a diferencia de versiones anteriores, he averiguado hasta el cansancio la forma de cómo estructurar dicha memoria exactamente igual que una VGA estándar, en cada uno de sus modos de texto y gráficos (por ahora solo está implementada la funcionalidad del modo de texto 80x25x16).

Como se ve, también se ha implementado capacidad de hacer un dump de todos los registros del CPU (y luego de regiones de memoria, de la memoria VGA, de los registros de cada periférico) y a la vez detener la emulación hasta que dejemos de revisar sus valores en busca de errores.

Esto literalmente hace posible que nuestro emulador se vuelva tan y más poderoso que emuladores tradicionales como 8086EMU o Emu8086, con un alto grado educativo para el desarrollador, una vez que implementemos más cosas.


Lo siguiente por hacer es implementar el 100% de las instrucciones de la 8086/8088, y esto nos dará la posibilidad de implementar un BIOS estándar a emular. También necesitamos implementar un teclado PS/2, tal como se muestra preliminarmente aquí:

Referencia Visual Interactiva de Valores de Teclas del Teclado
snap


Con esas cosas (CPU 8086 completo, teclado PS/2 y depuración mediante dumps de registros, memoria y periféricos), se nos hará posible depurar lo suficiente como para implementar una unidad de floppy, DMA, el timer, el controlador de interrupciones, y un BIOS estándar, y completar la emulación de la VGA estándar, y afinar la emulación de las regiones de memoria aunque una lectura o escritura atraviese dos regiones de tipos diferentes.

Teniendo esto, ya tendremos un emulador completo de PC 8086, el cual podremos escalar a una 386, y a una Pentium con PCI, FPU, gráficos Super VGA, mouse PS/2, CD/DVD emulado, disco duro emulado, sonido Sound Blaster y/o AC'97, y emulación de una conexión a Internet (emulando los paquetes de bajo nivel encapsulados en un XMLHttpRequest ordinario).

Una vez logardo eso, solo nos queda terminar de aprender sobre los estándares de hardware mediante su emulación/implementación, y gracias a esto podremos finalmente aprender de forma fácil y absolutamente completa, lenguajes como C, C++, y desde ahí profesionalizarnos. Unos 3 años sería un tiempo estimado bastante justo para lograr al menos el inicio de esto.

Todo desde un navegador con soporte para HTML5, incluso uno móvil con suficiente memoria, lo que le daría mucho más valor a todo el código clásico de PC, y le daría enorme portabilidad directo en el navegador.




El Siguiente Paso Concreto


El siguiente paso concreto es terminar de implementar el 100% de instrucciones de una 8086/8088. Juzgando por el tiempo que me llevó implementar las primeras 40-50 instrucciones, implementar el resto de instrucciones de 16 bits puros se llevaría no menos de 1 o 2 semanas (especialmente para instrucciones con prefijos, que las modifican y les dan un tamaño variable, impredecible de antemano, pero determinable).

Creo que voy a seguir escribiendo detalles variados a medida que termine de pensar bien cómo serían los siguientes pasos en el tramo actual de camino de implementación. Lo que he hecho hasta ahora, especialmente determinar las funciones de la VGA estándar, con decenas de registros y por lo menos unas 300 funciones internas a implementar, comenzando por la memoria, han sido un dolor de cabeza literal, pero que ya he superado, y con mayor habilidad como compensación, y la posibilidad de comenzar a ver la forma de un emulador de PC realmente útil en el mundo real, y extremadamente portable en infinidad de dispositivos móviles y de escritorio gracias a HTML5, y de volvernos especialistas en emulación a lo largo de los años.
Imagen
IP for hosts file (email udocproject@yahoo.com to get updates if website becomes offline):
Código: Seleccionar todo
190.150.9.244 archefire.org



See what I'm doing in real time:
Main Desktop 1
Main Desktop 2
Avatar de Usuario
~
Site Admin
 
Mensajes: 2958
Registrado: Sab Nov 10, 2012 1:04 pm

Re: Emulador de PC, VGA y el Resto de Periféricos

Notapor ~ » Mar May 07, 2013 2:58 am

NOTA: Agregué la propiedad target con un valor de _blank al elemento anchor que se usa para generar y descargar automáticamente un archivo de texto que contiene el dump de los registros.

Hice esto porque al usar el Tor Browser Bundle, en lugar de un diálogo de descarga se abría el archivo de texto con el dump de los registros en la misma ventana del emulador.

Con este cambio, ahora todos los navegadores deben abrir un diálogo de descarga del archivo generado o en su defecto, abrir una nueva pestaña (ya sea automáticamente o con permiso del usuario).
Imagen
IP for hosts file (email udocproject@yahoo.com to get updates if website becomes offline):
Código: Seleccionar todo
190.150.9.244 archefire.org



See what I'm doing in real time:
Main Desktop 1
Main Desktop 2
Avatar de Usuario
~
Site Admin
 
Mensajes: 2958
Registrado: Sab Nov 10, 2012 1:04 pm

Re: Emulador de PC, VGA y el Resto de Periféricos

Notapor ~ » Lun May 27, 2013 5:10 pm

La imagen anterior de BIOS hasta ahora:

Código: Seleccionar todo
;BIOS.asm



;This BIOS is thought to contain up to 64K by now,
;so it should start with a base address of 0, to
;start at the beginning of this code segment:
;;
 org 0000h


;Point stack segment
;register to somewhere
;temporarily reasonable:
;;
 xor ax,ax
 mov ss,ax


 mov ax,0x500
 mov sp,ax




;Point main data segment
;registers to the start of
;the current segment:
;;
 push cs
 pop ax
 mov ds,ax
 mov es,ax







jmp Main

sstr db "Hi Z86!",0


Main:


;call clrscr
;;
   mov si,_clr
   mov di,1
    call prn_str


mov si,sstr
mov di,0
 call prn_str




;Debug by dumping CPU regs:
;;
 out 0xFF,al






;;;INIT: Set up interrupt vector for PIT
;;;INIT: Set up interrupt vector for PIT
;;;INIT: Set up interrupt vector for PIT
;;;INIT: Set up interrupt vector for PIT

 push ds

    ;Set DS to 0, so to start at the very
    ;start of the whole RAM, where the Real-Mode
    ;IDT is located:
    ;;
     xor ax,ax
     push ax
     pop ds


    ;Set IP of interrupt vector to the address
    ;of the routine called "irq0" (the "irq0"
    ;source code label):
    ;;
     mov ax,irq0
     mov word[0],ax


    ;Set CS of interrupt vector to current CS
    ;(this segment's CS):
    ;;
     push cs
     pop ax
     mov word[2],ax



 pop ds


;;;END:  Set up interrupt vector for PIT
;;;END:  Set up interrupt vector for PIT
;;;END:  Set up interrupt vector for PIT
;;;END:  Set up interrupt vector for PIT













 ;Instead of freezing interrupts and the CPU,
 ;we will stay in an idle loop for being aboe to respond to
 ;hardware interrupts. In the meantime, instead of just
 ;looping, we will use an HLT instruction to avoid
 ;wasting too much CPU power, and wake up the current
 ;CPU core only when an IRQ is executed:
 ;;
  sti


    jmp 0x0000:0x7C00


  .ll:
    hlt
  jmp .ll



;Inputs:
;      SI == source string
;      DI == destination mem
;
;;
prn_str:
 push es
 push si
 push di

 mov ax,0xB800
 mov es,ax

 .l:


   lodsb

   cmp al,0
   je .l_END

     stosb
     inc di

   jmp .l


 .l_END:



 pop di
 pop si
 pop es
ret













clrscr:
 push es
 push ax
 push cx
 push di

  mov ax,0xB800
  mov es,ax
  mov ax,0x0720
  mov cx,(80*25)
  mov di,0

   rep stosw


 pop di
 pop cx
 pop ax
 pop es


ret



%include "fonts/8x16_default_font.asm"
%include "vgaregs/config_regs_EGA_t80x25x16.asm"
%include "vgaregs/config_regs_MCGA_320x240_ModeX.asm"
%include "vgaregs/config_regs_MCGA_g320x200x256__13h.asm"
%include "vgaregs/config_regs_VGA_g640x480x16__12h.asm"
%include "vgaregs/PALETTE_80x25x16.asm"
%include "vgaregs/PALETTE_320x200x256.asm"



_clr times 80*25 db 0x07
                 db 0








irq0:

push ds
push es
push ax
push si
push di


 mov ax,0xB800
 mov ds,ax
 mov es,ax



 ;For each timer interrupt,
 ;show that fact by increasing
 ;the first character on screen:
 ;;
;  inc byte[0]    ;[ADD OPCODE]



  xor si,si
  xor di,di
  lodsb
;  inc al    ;[ADD OPCODE]
  inc ax
  stosb



 ;Let's acknowledge the IRQ (IRQ0):
 ;;
  mov al,0x20
  out 0x20,al



pop di
pop si
pop ax
pop es
pop ds
iret    ;[ADD OPCODE]






;Our current implementation of the BIOS loader
;requires the BIOS to be aligned to 16 bytes:
;;
 align 16

Imagen
IP for hosts file (email udocproject@yahoo.com to get updates if website becomes offline):
Código: Seleccionar todo
190.150.9.244 archefire.org



See what I'm doing in real time:
Main Desktop 1
Main Desktop 2
Avatar de Usuario
~
Site Admin
 
Mensajes: 2958
Registrado: Sab Nov 10, 2012 1:04 pm

Re: Emulador de PC, VGA y el Resto de Periféricos

Notapor ~ » Mié Jun 12, 2013 4:41 pm

Actualmente este emulador tiene 43 instrucciones de 16 bits implementadas y es capaz de determinar desborde (overflow), acarreo (carry) para números binarios y BCD, paridad, y el signo de las operaciones aritméticas. Muchas de estas instrucciones abarcan 4 u 8 valores de byte para el opcode, así que estamos prácticamente a la mitad de la implementación de todas las instrucciones de una 8086.

Lo más difícil que queda entre todas las instrucciones es manejar la cantidad de instrucciones a implementar, pero sobre todo, implementar correctamente la funcionalidad de los prefijos de repetición, de sobrepasado de registros de segmento, de bloqueo de memoria, y de tamaño de operando/dirección (en preparación para abrir camino a implementar instrucciones al nivel de una 386 y posterior, para código de 32 bits).

He implementado el mecanismo de IRQs e interrupciones, y un PIT (timer programable de intervalos) con la frecuencia por defecto de 18.2 Hertz para ayudarme a comprobar que la implementación era correcta, dado que al ejecutar la instrucción hlt con interrupciones activadas el CPU emulado se detenga y sea reanudado con las IRQs emuladas.

También he implementado funcionalidad para que el esqueleto del BIOS implementado actualmente pueda cargar un programa (blob) en la dirección de boot 07C0:0000 para evitar alterar la imagen del BIOS en cuestión y volverla escalable, ordenada, y que llegue a ser un verdadero BIOS estándar para nuestro emulador. La dirección 07C0:0000 es mejor que usar la dirección 0000:7C00 porque esto nos da directamente un segmento de 65536 bytes sin necesidad de reubicar las direcciones de las etiquetas/identificadores en el código. De lo contrario también quedaríamos con menos de 65536 bytes (tendríamos poco menos de la mitad).





Con todo esto es necesario implementar instrucciones adicionales, y para eso estoy usando muchos programas de un kit de pruebas que yo mismo estoy desarrollando, tanto para cada instrucción como para aplicaciones de prueba (snippets).

Por ejemplo, actualmente estoy trabajando con el siguiente snippet a emular, y solo hay 2 instrucciones que necesito implementar (el resto ya están presentes y se pueden interpretar):

Blob_Image.asm
Código: Seleccionar todo
START:


org 0

;Point main data segment
;registers to the start of
;the current segment:
;;
 push cs
 pop ax
 mov ds,ax
 mov es,ax





;Calculate total number of bits:
;;
 mov al,[num0]
 add al,[num1]






;sti
xor bx,bx
.l:
 call VGAVideo_CRTC_setTextCurPos
 inc bx
  cmp bx,1999
  jb .nolim
    xor bx,bx

  .nolim:

  hlt
jmp .l









num0 db 3

num1 db 6




%include "vgatxtcur.asm"




align 16



vgatxtcur.asm
Código: Seleccionar todo
;Inputs:
;      BX == Cursor offset (0 to 65535).
;            Actually, these VGA registers don't take
;            into account the hidden attribute bytes, so
;            for them, a screen of 80x25 just has cursor
;            offsets that range from 0 to 65535,
;            of which only 0 to 1999 are visible.
;;
 VGAVideo_CRTC_setTextCurPos:
  push ax
  push bx
  push dx

       mov al,14      ;reg 14 (MSB)
       mov ah,bh      ;MSB value
       mov dx,03D4h   ;index reg
       out dx,ax      ;specify r/w to CRTC port 14

       mov al,15      ;reg 15 (LSB)
       mov ah,bl      ;LSB value
       mov dx,03D4h   ;index reg
       out dx,ax      ;specify r/w to CRTC port 15


  pop dx
  pop bx
  pop ax
 ret





Las instrucciones que necesito implementar del código anterior son CMP (opcode 0x81) y JB (opcode 0x72).
Imagen
IP for hosts file (email udocproject@yahoo.com to get updates if website becomes offline):
Código: Seleccionar todo
190.150.9.244 archefire.org



See what I'm doing in real time:
Main Desktop 1
Main Desktop 2
Avatar de Usuario
~
Site Admin
 
Mensajes: 2958
Registrado: Sab Nov 10, 2012 1:04 pm

Re: Emulador de PC, VGA y el Resto de Periféricos

Notapor ~ » Vie Jun 14, 2013 9:01 pm

Para la instrucción cmp (opcode 0x81), lo primero que debemos ver es que el primer operador puede ser un registro o tal vez una ubicación de memoria, todos de 16 bits siempre, y el segundo operador siempre es un valor inmediato.

El manual nos dice que este opcode 0x81 usa un byte ModR/M y que maneja datos de 16 bits, así que sabemos que esta instrucción de hecho puede seleccionar entre registros y offsets de memoria.

El manual también nos dice que este opcode solamente usa los campos Mod y R/M del byte ModR/M. También el hecho de que el campo Reg se usa como una "extensión" de ese opcode, lo que significa que el opcode base 0x81 puede significar más de una única instrucción, como podemos comprobarlo si usamos, por ejemplo 0xC3 en lugar de 0xFB como valor del byte ModR/M.

Dado que 0xFB tiene el valor 7 en el campo Reg, y dado que la instrucción pide que el valor de Reg sea 7 para que el opcode 0x81 signifique cmp, entonces la instrucción ejecutar es cmp efectivamente.

Pero dado que 0xC3 tiene los mismos valores para los campos Mod y RM que 0xFB, aunque con un valor de campo Reg diferente (en este caso 0), eso significa que el opcode base 0x81 significa otra instrucción (en este caso, en el que es 0, eso nos indica que la instrucción a ejecutar efectivamente es add).
Imagen
IP for hosts file (email udocproject@yahoo.com to get updates if website becomes offline):
Código: Seleccionar todo
190.150.9.244 archefire.org



See what I'm doing in real time:
Main Desktop 1
Main Desktop 2
Avatar de Usuario
~
Site Admin
 
Mensajes: 2958
Registrado: Sab Nov 10, 2012 1:04 pm

Re: Emulador de PC, VGA y el Resto de Periféricos

Notapor ~ » Vie Jun 14, 2013 10:43 pm

El opcode 0x81, por lo menos para las instrucciones de propósito general del CPU, es capaz de ejecutar 8 instrucciones diferentes, todas con el mismo par de operadores pero obviamente aplicándoles operaciones diferentes:

/0 -- add r/m16, imm16
/1 -- or r/m16, imm16
/2 -- adc r/m16, imm16
/3 -- sbb r/m16, imm16
/4 -- and r/m16, imm16
/5 -- sub r/m16, imm16
/6 -- xor r/m16, imm16
/7 -- cmp r/m16, imm16
Imagen
IP for hosts file (email udocproject@yahoo.com to get updates if website becomes offline):
Código: Seleccionar todo
190.150.9.244 archefire.org



See what I'm doing in real time:
Main Desktop 1
Main Desktop 2
Avatar de Usuario
~
Site Admin
 
Mensajes: 2958
Registrado: Sab Nov 10, 2012 1:04 pm

Re: Emulador de PC, VGA y el Resto de Periféricos

Notapor ~ » Sab Jun 15, 2013 4:32 am

Una vez que hemos implementado el opcode 0x81 y el 0x72, se puede ver el efecto del snippet anterior, que simplemente está diseñado para hacer avanzar el cursor de texto en cada tick del timer del sistema, que tiene 18.2 Hertz por defecto (obviamente estamos emulando todo eso) y una vez que alcance la parte inferior de la pantalla es regresado al principio.

Para poder implementar todo lo anterior, especialmente las instrucciones, tuve que crear una subtabla para hacer espacio para las diferentes funciones del opcode 0x81, y finalmente estoy creando funciones centralizadas para evitar duplicar innecesariamente el código de interpretación de los diferentes pares de operadores, en los que solamente cambia la operación a realizar, que por ahora son los dictados por el byte ModR/M.

Esto no lo había hecho hasta ahora porque no había llegado a un punto en el que pudiera distinguir fácilmente qué funcionalidad se podía empacar de forma genérica para su reutilización.

En otras palabras, lo que queda por hacer actualmente es agregar la funcionalidad nueva de la forma más reutilizable posible, para que eso haga muy fácil implementar el resto de instrucciones. Seguramente este inicio es una demostración de que con el camino por el que vamos, el poder implementar todas las instrucciones es una cuestión de tener mucho código de prueba que correr de forma precisa, y después de eso terminar de implementar la funcionalidad de los periféricos y suficientes funciones que sean más inmediatamente relevantes del BIOS.
Imagen
IP for hosts file (email udocproject@yahoo.com to get updates if website becomes offline):
Código: Seleccionar todo
190.150.9.244 archefire.org



See what I'm doing in real time:
Main Desktop 1
Main Desktop 2
Avatar de Usuario
~
Site Admin
 
Mensajes: 2958
Registrado: Sab Nov 10, 2012 1:04 pm

Re: Emulador de PC, VGA y el Resto de Periféricos

Notapor ~ » Dom Jun 30, 2013 8:35 pm

Tengo la idea de agregar la capacidad de inyectar contenido binario a cualquier dirección arbitraria de memoria en tiempo de ejecución, para así poder probar diferentes conjuntos de datos y hacer que este emulador comience a ser algo realmente útil.

Por ejemplo, podría cargar los datos de sprites de Sonic 3D Blast, y si implemento un modo Super VGA de 640x480x256 colores, entonces estaremos dando paso a una aplicación realmente interesante.

Podemos entonces usar el primer byte de esos datos como bandera para que el programa se detenga, se reinicie o comience a analizar los datos, y así poder cargar esos datos interactivamente.

Esto nos permitirá reutilizar todo nuestro conocimiento de nivel de sistema, de modo que no tengamos que aprender demasiadas herramientas nuevas y así volvernos ineficientes, a la vez que comenzaremos a explorar todo tipo de cosas cada vez más avanzadas, en un nuevo entorno intermedio entre Ensamblador y HTML/HTML5/JavaScript, que es lo más estandarizado y a la vez amigable en el mundo de la programación.

En otras palabras, todo un éxito, que se volverá cada vez mayor, a medida que emulemos más y aprendamos más algoritmos avanzados.
Imagen
IP for hosts file (email udocproject@yahoo.com to get updates if website becomes offline):
Código: Seleccionar todo
190.150.9.244 archefire.org



See what I'm doing in real time:
Main Desktop 1
Main Desktop 2
Avatar de Usuario
~
Site Admin
 
Mensajes: 2958
Registrado: Sab Nov 10, 2012 1:04 pm

Re: Emulador de PC, VGA y el Resto de Periféricos

Notapor ~ » Dom Jun 30, 2013 9:04 pm

Desde que implementé el modo gráfico de 256 colores, y desde que estoy tratando de correr un pequeño demo VGA de fuego, he visto que siempre que no puedo hacer algo es porque estoy tratando de resolverlo a un nivel en el que todo es muy avanzado para mí dado que no tengo todas las bases necesarias para lograr resolverlo.

Así que he aprendido que lo que debo hacer es tratar de resolver un problema fundamentalmente del mismo tipo, con los mismos requerimientos, pero menos elementos presentes a la vez del problema real. Por ejemplo, lo que traté de hacer originalmente fue correr el juego de Zazzon para la 8088 pero eso fue muy difícil, dado que había demasiadas instrucciones de CPU y demasiada funcionalidad gráfica a la vez como para comprobar que todo estaba bien sino hasta que terminara de implementar, que para entonces seguramente habría producido muchos errores difíciles de siquiera encontrar.

Así que lo siguiente que hice fue tratar de correr el demo de fuego, que tenía menos instrucciones, y poca funcionalidad gráfica, aunque en el modo 320x200x256 en lugar del 320x200x4, pero que en realidad era más fácil de implementar.

Ya que también fallé en este demo, hice un demo todavía más simple, que escribe toda la pantalla con valores 0 a 255 secuencialmente y después cambia los valores de la paleta, incrementándolos, para lo cual tuve que implementar esa funcionalidad y el refrescado de la pantalla debido a la paleta. Esto lo resolví bien, así que ahora estoy nuevamente tratando de resolver el demo de fuego, y una vez que encuentre algún requerimiento concreto a resolver, si no lo puedo resolver en ese demo, crearíe otro pequeño problema separado conteniendo ese mismo requerimiento, y cuando lo resuelva volveré a intentar resolver el problema inmediatamente más difícil y que sea mayor, en este caso el demo de fuego; y así sucesiva e iterativamente.

Así que esto me demuestra mantener una cadena documentada de problemas del mismo tipo y mientras haya más que lo que pueda manejar, debo buscar algo igual en requerimientos pero más simple. Una vez que logre resolver por completo el eslabón de la cadena que sea más complejo, debo avanzar e intentar ver si puedo resolver el siguiente más difícil, y si este todavía es demasiado difícil, debo buscar un eslabón más simple, que contenga las cosas que debo resolver y que también están presentes en el eslabón inmediatamente más difícil.

Debo hacer esto hasta que llegue un punto en el que resuelva todos los requerimientos de tal forma que cubra todos los de los pequeños problemas, y que a su vez esos requerimientos sean todos los del problema más complejo.

Esta es la forma de obtener resultados lo más inmediatamente posible en asuntos que de otra forma y por naturaleza, entregan resultados solo después de estar completas del todo, así que en lugar de completarla en un único enorme intento, lo resolveremos a través de pequeños problemas autónomos que representen las diferentes exigencias del verdadero problema a resolver.

Así obtendremos gratificación instantánea al ver cómo pequeñas cosas interesantes funcionan por nuestra propia mano, y cómo lograremos resolver más pronto de lo que esperábamos, incluso los problemas más complejos.





La señal que nos indica que debemos llevar a cabo el procedimiento anterior es cuando, a pesar de todos nuestros esfuerzos, patinamos en un mismo punto y sin avanzar, de forma consistente, durante un tiempo prudencial, para un problema.
Imagen
IP for hosts file (email udocproject@yahoo.com to get updates if website becomes offline):
Código: Seleccionar todo
190.150.9.244 archefire.org



See what I'm doing in real time:
Main Desktop 1
Main Desktop 2
Avatar de Usuario
~
Site Admin
 
Mensajes: 2958
Registrado: Sab Nov 10, 2012 1:04 pm

Re: Emulador de PC, VGA y el Resto de Periféricos

Notapor ~ » Lun Jul 15, 2013 4:45 pm

En el tiempo que ha pasado (casi 14 días), he logrado agregar componentes importantes al emulador:

  • Puedo cambiar, con calidad de código de depuración aunque muy funcional, entre los modos de video con sua funcionalidad fundamental, de los modos de texto 80x25x16 colores, y los modos gráficos 320x200x4 colores y 320x200x256 colores. He implementado la llamada de BIOS del INT 10h, Servicio AH=0 (Cambiar Modo de Video) para hacer que dicho cambio de modos de video sea utilizable de forma estándar desde este momento desde nuestros programas de prueba.

  • He implementado 52 instrucciones del CPU, y 3 de estas son extensiones de 3 instrucciones cada una, así que puedo llegar potencialmente a alrededor de 80 instrucciones emuladas.

  • Hice que el CPU emulado corriera un poco más rápido al cambiar el parámetro de intervalo de tiempo, de 0 a 1, para la llamada de setInterval para el hilo del CPU emulado.

  • Finalmente puedo usar prefijos de instrucciones, y en este momento he implementado el prefijo para repetir instrucciones de cadenas de caracteres, lo que me permite mover bloques de memoria de un punto a otro en la memoria con una única instrucción.





Lo que ahora estoy tratando de hacer es tratar de terminar en lo que queda entre este día y mañana toda la funcionalidad necesaria para correr el siguiente demo gráfico de un efecto de fuego en modo 320x200x256 colores (lo que abre la posibilidad de eventualmente correr todo tipo de demos gráficos de x86 de 16 bits en cualquier PC, tablet e incluso teléfono con un navegador moderno, buena cantidad de memoria y soporte completo de HTML5, sin importar el sistema operativo subyacente):

Código: Seleccionar todo
org 0h



ENTRY:  ;jmp     START

;******************* Procedure to set the palette *********************;
;  For I :=1 to 32 do
;    palette(I,2*I-1,I,0);
;    palette(I+31,63,I+31,0);
;    palette(I+31,63,63,2*I-1);
;    palette(I+31,63,63,63);



;******************** Main program ****************************;
START:
        mov     ah,0
        mov     al,13h
   int     10h
   mov     ax,0A000h
   mov     ds,ax
;------------------------------------
;   the pallet routine
;------------------------------------

   xor   cx,cx ;
   dec   cx

   mov   ah,2
AQ:
   add   cl,ah      ;add 2
CLR2:
   inc     ch
CLR:
   inc     bx
   mov     al,bl
   mov     dx,03C8h
   out     dx,al           ; Palette number
   inc     dx
   mov     al,cl
   out     dx,al           ; Red
   mov     al,ch
   out     dx,al           ; Green
   mov     al,bh
   out     dx,al           ; Blue

   cmp     bl,32           ; If bl < 32 then create palette set 1
   jb      AQ             
A1:

      cmp     bl,64           ; If bl > 63 then adjust 2nd palette
   jb     CLR2
A2:
      cmp     bl,95           ; If bl > 63 then adjust 3rd palette
   ja      A3
   add   bh,ah

A3:
;----------
      cmp     bl,128          ; Make last 32 colours white
   jb      CLR
A4:
;------------------------------------
;------------------------------------

 
MLoop1: xor     si,si           ; X :=0
MLoop2: mov     cx,110          ; Y :=100  (was 60)
MLoop3: mov     ax,320

   mul     cx
   add     ax,si           ; AX :=Y*320 + X
   mov     di,ax

   mov     bx,0-320d


   
   movzx   dx,[di-1]        ; mem[$A000:y * 320 + x - 1]

   movzx   ax,[di]         ; mem[$A000:y * 320 + x]
   add     dx,ax           ; add and save colors

   mov     al,[di+1]         ; mem[$A000:y * 320 + x + 1]
   add     dx,ax           ; Add and Save color

   mov     al,[di+321]         ; mem[$A000:(y+1) * 320 + x + 1]
   add     dx,ax           ; Add and save color
   shr     dx,2            ; Color DIV 4

   je      cont
   dec     dx


cont:
   mov     [di+bx],dl         ; mem[$A000:(y-1)*320 + x] := ax
   mov     [di-160],dl

   inc     cx
   cmp     cx,202
   jle     MLoop3          ; Until Y > 202

; Generate random number  =>  random(4)
   mov     dx,3DAh         ;
   in      al,dx           ; get random number 0..255
   xor     al,[di+bx]   ; more random
      and     al,11b          ; mod 4
      mov     dl,68           ;68  164
   mul     dx
   mov     [di],al
   
   inc     si              ; X :=X+1
   cmp     si,160
   jl      MLoop2          ; Until X >= 320

   jmp     MLoop1

align 16



Considero que estoy bastante cerca de lograr correr ese código, ya que a lo sumo me hace falta implementar poco menos de la mitad de las instrucciones usadas. Después de eso simplemente me hace falta implementar el comportamiento de la paleta RGB de 256 colores al momento de su escritura, para actualizar los colores en pantalla tan pronto como se cambien los colores en la paleta.

Esto es relativamente poco comparado con todo lo que he tenido que escribir del emulador hasta ahora.
Imagen
IP for hosts file (email udocproject@yahoo.com to get updates if website becomes offline):
Código: Seleccionar todo
190.150.9.244 archefire.org



See what I'm doing in real time:
Main Desktop 1
Main Desktop 2
Avatar de Usuario
~
Site Admin
 
Mensajes: 2958
Registrado: Sab Nov 10, 2012 1:04 pm

Re: Emulador de PC, VGA y el Resto de Periféricos

Notapor ~ » Lun Jul 15, 2013 4:49 pm

Para quienes deseen ver el efecto de este demo animado con una ejecución de código emulado, ver lo interesante que resulta lograr dicho efecto en HTML5 y recibir el código del emulador, simplememente dar clic en el link del emulador:

Emulador de PC x86 de 16 bits en HTML5 (versión 2013-06-30)

También pueden obtener el código fuente en un ZIP como un archivo aquí:

ZIP x86Emu_2013-06-30.zip

En las horas que han pasado, finalmente he logrado implementar la funcionalidad de la paleta de colores, y asociarla a esta con el modo 320x200x256 colores, y asociarla con el resto de modos gráficos sería un trabajo simplemente de copiar, pegar y modificar las pocas características de cada modo (por lo menos al nivel de desarrollo actual de la emulación).

He agregado la capacidad con puertos de depuración, y también desde la interfaz del emulador, dos botones, uno para hacer dump de los registros del CPU y otro para hacer dump de la memoria RAM (sin contar la memoria de video, que está en otro búfer separado):

Image




Aquí está el programa que he logrado correr. Por ahora todavía no puedo correr el demo de efecto de fuego porque una o más de las instrucciones que agregué en este ciclo tienen errores:

Este es el código de Ensamblador del programa que vemos corriendo:

Código: Seleccionar todo
org 0

START:

;Apuntar el segmento principal de datos
;al inicio del segmento actual (probablemente innecesario
;para este demo):
;;
 push cs
 pop ax
 mov ds,ax
 mov es,ax



;Establecer el Modo 13h (320x200x256):
;;
 mov ax,13h
 int 10h




;Efectuar pruebas de memoria llenándo secuencialmente la memoria
;de video visible (64000 bytes exactamente) con los valores 0-255,
;que corresponden a los 256 colores:
;;
 mov ax,0xA000
 push ax
 pop es
 xor di,di
 xor ax,ax

  ;Escribir un pixel en pantalla:
  ;;
   mov cx,(320*200)



;Agregar REP STOSB aquí, y mejorarlo para que sea mucho más rápido,
;tal vez procesando hasta 4096, 8192, 16384 o 65536 bytes a la vez
;sin tener que recorrer la ruta completa de emulación
;de la instrucción sino que repetir localmente la instrucción
;STOSB mientras no alcancemos el tamaño acelerado del bloque
;y mientras CX no sea 0.


  .ll:
   stosb

   inc ax
  dec cx
  jnz .ll






;Establecer los registros de índice de lectura
;y escritura de la paleta a 0, para que primero podamos
;leer y luego escribir la paleta sin necesidad de variables.
;
;Como sabe cualquiera que ha programado este modo
;anteriormente, esto hará que los colores en pantalla cambien
;sin modificar el contenido de la memoria de video, sino solo
;los colores de la paleta representados para esos valores
;en memoria:
;;
 xor ax,ax
 mov dx,0x3C7
 out dx,al
 mov dx,0x3C8
 out dx,al


;Apuntar al registro de datos de la paleta
;del cual leeremos los componentes R, G y B
;uno a la vez, y luego aumentaremos sus valores
;para luego escribirlos así::
;;
 mov dx,0x3C9


sti
.l:

 ;Hacer ciclo a la paleta:
 ;;
  in al,dx
  add ax,9
  out dx,al
    in al,dx
    add ax,13
    out dx,al
      in al,dx
      add ax,25
      out dx,al


  hlt
jmp .l

align 16



Image

Image

Image

Image

Image






Aparte de esto, he llegado a las 60 instrucciones base implementadas para el CPU. Entre otras, tuve que implementar las instrucciones INT, JL, JLE, XOR, MOVZX, JA, AND, y SHR, entre otras combinaciones de índices ModR/M. En una o más de esas instrucciones está el error que no me permite correr todavía el demo de efecto de fuego. Este es el inicio de un nivel realmente formal de emulación, y tan pronto como solucione los errores y deficiencias del código existente, eso va a permitir dejar lecciones importantes para implementar lo que sigue, que es menos básico que hasta ahora, y como prueba de que se ha logrado dominar todo lo requerido para este nivel, ese demo de fuego debe funcionar sin excepción.


Aspectos de HTML5

Como he podido comprobar con este emulador, la escritura a un Canvas pixel a pixel siempre es muy lenta. Quien diga que técnicas de doble buffering o similares ya no son necesarias para mejorar la eficiencia de un elemento Canvas está equivocado.

Lo que he tenido que hacer aquí es mantener, aparte del Typed Array del Canvas mismo, otro Typed Array aparte, y escribirlo a 30 cuadros por segundo, pero ÚNICAMENTE si hubo algún cambio en la memoria o en la paleta de color (para ahorrarse las múltiples ocasiones en las que mover los datos inalterados del segundo búfer al búfer visible del Canvas no sería más que desperdicio de CPU).

La ejecución del hilo del CPU también es muy lenta, limitada por la velociddad de 1 milisegundo como la más rápida posible de cada tick de setInterval. Para mejorar eso, he tenido que ejecutar un bucle de 65536 o 131072 iteraciones para cada tick de ese hilo de timer para el CPU. Aun así, el CPU, junto con el video emulado, son hasta ahora las cosas más lentas, más problemáticas a emular en cuanto a la velocidad óptima, porque sus contrapartes de HTML5 son demasiado ineficientes (escribir pixel a pixel, leer unos cuantos bytes) si las comparamos con otros lenguajes (incluso Java y Flash puede que sean más eficientes, así que hay mucho camino que los navegadores deben recorrer en este aspecto).

El navegador más rápido en ejecutar fue Chrome, seguido por Firefox, y después Opera. Lo malo de Chrome es que no permite correr localmente sin switches especiales de línea de comandos, a diferencia de Firefox, pero si hemos de tener un buen emulador, tenemos que aprender y aplicar optimizaciones que no dependan de un motor particular de JavaScript.



Sobre usar Web Workers en el estado actual

Tratar de usar Web Workers podría no ser muy fácil y mucho menos elegante, ya que si defino un Web Worker, por ejemplo, para el hilo del CPU, uno de los peores efectos sería que no podría acceder la memoria RAM emulada desde ese hilo de Web Worker, ya que dichos Web Workers no tienen acceso a ningún objeto en el hilo principal de una página HTML y su código de JavaScript. Y usar objetos transferibles haría que, por ejemplo, al transferir la RAM a un hilo cualquiera, este dejaría de existir en el scope global, así que esa no es directamente una solución.

Agregar hilos de este tipo requeriría mucho análisis adicional, pero de lograrse sería extremadamente beneficioso, para lograr máxima fluidez para lo siguiente:

1. Ejecutar el código de Ensamblador emulado en un bucle, a la velocidad máxima real del CPU.

2. Lograr concurrencia máxima de todos los periféricos emulados, cada uno en su propio hilo.

3. El hilo principal, el de la página web y la GUI del navegador, serviría simplemente para administrar el resto de todos los hilos y mantener la GUI, y ya no para mantener todos los objetos relevantes (aunque esto es lo más difícil de lograr con Web Workers, por lo menos en su estado actual, según parece).
Imagen
IP for hosts file (email udocproject@yahoo.com to get updates if website becomes offline):
Código: Seleccionar todo
190.150.9.244 archefire.org



See what I'm doing in real time:
Main Desktop 1
Main Desktop 2
Avatar de Usuario
~
Site Admin
 
Mensajes: 2958
Registrado: Sab Nov 10, 2012 1:04 pm

Re: Emulador de PC, VGA y el Resto de Periféricos

Notapor ~ » Lun Jul 15, 2013 4:53 pm

He resuelto todos los errores que he podido, especialmente de las instrucciones de comparación CMP, la instrucción MUL para multiplicación, y la forma de procesar la bandera de Overflow (Desborde) y de Signo para 8 bits, la cual estaba siendo colocada en la posición de la bandera de Cero (ZF).

Para instrucciones como XOR y MUL, todavía me hace falta agregar el cálculo de cada una de sus banderas pertinentes, así que un programa fallaría si dependiera del estado de esas banderas según se establecen por esas instrucciones particulares.

Finalmente he logrado correr el demo de efecto de fuego del que hablaba, y para verlo en acción simplemente hay que dar clic en la siguiente imagen que demuestra cómo se ve, corriendo en el emulador de PC x86 de 16 bits en HTML5.

Para poder guardar el gráfico generado en el Canvas, en la mayoría de navegadores es posible simplemente dar clic derecho sobre el Canvas para guardarlo como si se tratara de una imagen regular.

El código fuente del emulador y del programa de Ensamblador, en código fuente y en binario a procesar, está en el siguiente ZIP:

www.winzip.com.ico x86Emu__2013-07-03-jansflame.zip

jansflame


jansflame


El código final es este:

Código: Seleccionar todo
org 0h

cli


ENTRY:  ;jmp     START

;******************* Procedure to set the palette *********************;
;  For I :=1 to 32 do
;    palette(I,2*I-1,I,0);
;    palette(I+31,63,I+31,0);
;    palette(I+31,63,63,2*I-1);
;    palette(I+31,63,63,63);



;******************** Main program ****************************;
START:

;        mov     ah,0
;        mov     al,13h
    mov ax,13h
   int     10h

   mov     ax,0A000h
   mov     ds,ax
   mov     es,ax
;        xor si,si
;        xor di,di


;mov di,(320*200)-1
;mov al,255
;stosb


;mov di,(320*200)-1
;xor bx,bx
;mov dl,200
;   mov     [di+bx],dl         ; mem[$A000:(y-1)*320 + x] := ax

;out 0xFF,al
;cli
;hlt


;mov dl,127
;mov di,320
;   mov     [di-160],dl
;   out 0xFF,al




;------------------------------------
;   the pallet routine
;------------------------------------

   xor   cx,cx ;
   dec   cx

   mov   ah,2
AQ:
   add   cl,ah      ;add 2
CLR2:
   inc     ch
CLR:
   inc     bx
   mov     al,bl
   mov     dx,03C8h
   out     dx,al           ; Palette number
   inc     dx
   mov     al,cl
   out     dx,al           ; Red
   mov     al,ch
   out     dx,al           ; Green
   mov     al,bh
   out     dx,al           ; Blue
   cmp     bl,32           ; If bl < 32 then create palette set 1
   jb      AQ             
A1:

      cmp     bl,64           ; If bl > 63 then adjust 2nd palette
   jb     CLR2
A2:
      cmp     bl,95           ; If bl > 63 then adjust 3rd palette
   ja      A3
   add   bh,ah

A3:
;----------
      cmp     bl,128          ; Make last 32 colours white
   jb      CLR
A4:
;------------------------------------
;------------------------------------


 
MLoop1: xor     si,si           ; X :=0
MLoop2: mov     cx,110          ; Y :=100  (was 60)
MLoop3: mov     ax,320

   mul     cx
   add     ax,si           ; AX :=Y*320 + X
   mov     di,ax

   mov     bx,0-320d



   
   movzx   dx,[di-1]        ; mem[$A000:y * 320 + x - 1]

   movzx   ax,[di]         ; mem[$A000:y * 320 + x]







   add     dx,ax           ; add and save colors

   mov     al,[di+1]         ; mem[$A000:y * 320 + x + 1]
   add     dx,ax           ; Add and Save color

   mov     al,[di+321]         ; mem[$A000:(y+1) * 320 + x + 1]
   add     dx,ax           ; Add and save color
   shr     dx,2            ; Color DIV 4


   je      cont
   dec     dx


cont:
    ;This instruction has
    ;problems with ints on:
    ;;
   mov     [di+bx],dl         ; mem[$A000:(y-1)*320 + x] := ax


;push ax
;push di
;
;add di,bx
;mov al,dl
;stosb
;
;;out 0xFF,al
;
;pop di
;pop ax



   mov     [di-160],dl

   inc     cx
   cmp     cx,202
   jle     MLoop3          ; Until Y > 202

; Generate random number  =>  random(4)
   mov     dx,3DAh         ;
   in      al,dx           ; get random number 0..255
;   xor     al,[di+bx]   ; more random
;      and     al,11b          ; mod 4
;      mov     dl,68           ;68  164






;out 0xFD,al
;out 0xFF,al
;cli
;hlt





   mul     dx






   mov     [di],al






   
   inc     si              ; X :=X+1
   cmp     si,160
   jl      MLoop2          ; Until X >= 320

   jmp     MLoop1

align 16



Lo que Queda por Hacer

Necesito completar absolutamente todas las funciones para todas las funciones de combinaciones de los campos Mod y R/M y Reg. También necesito crear un kit de pequeños programas de prueba para cada instrucción actualmente implementada que pueda correr en una máquina real usando algo como DEBUG.COM y también pueda correr directamente en el emulador haciendo uso de diferentes valores, y evaluando las discrepancias entre los dos, para solucionar tales errores.

Desafortunadamente, al menos en mi laptop a 1.5 GHz y 2 GB de RAM, la emulación gráfica es en realidad demasiado lenta, y probablemente es peor ya que para la emulación de los modos de 320x200 o 320x240, cada pixel en el Canvas de HTML5 realmente es un área de 2x2 pixeles (es decir 4 pixeles, que es un total de 16 bytes). Si después de haber completado la emulación y las optimizaciones todo sigue siendo lento, es posible que use realmente un Canvas de 320x200 o 320x240 para que la emulación sea suficientemente rápida como para ser utilizable en cualquier circunstancia.

Lo que queda, después de asegurarse de que las instrucciones actuales no tienen errores, es crear varios programas de validación para cada nueva instrucción agregada, para compararla con los resultados de un CPU real, y cuando tengamos suficientes instrucciones para un programa mayor, correrlo a este para verificar que efectivamente todo está bien.

Para hacer esto efectivo en el mundo real, voy a buscar muchos más programas de prueba que sean de provecho, como el mostrado anteriormente, y una vez que tengamos implementadas todas las instrucciones del CPU 8088, podemos comenzar a implementar los periféricos, como el teclado, el timer, el DMA y el floppy, además de una cantidad mínima de servicios de interrupción del BIOS y del DOS, con el objetivo de poder eventualmente correr MS-DOS u otro DOS para 8088, y muchas de sus programas.



Sobre la Dependencia a Una VGA Real del Programa de Fuego

El programa lee el puerto 0x3DA (puerto de Reseteo del Flip/Flop del Controlador de Atributos) de una VGA real, que tiene cierta "aleatoriedad", aunque realmente no es tan aleatorio. En una VGA real, las llamas de este programa suelen verse mucho más separadas entre sí, como si fueran las de un fósforo. En una VGA real, el valor devuelto por este puerto también proporciona la mayoría del control de velocidad.

En este emulador, he implementado el mejor valor aleatorio que he podido hasta ahora y que está dado por esta línea de código, cuando se lee ese puerto emulado 0x3DA:

Código: Seleccionar todo
return (((Math.random()*7)|0)+3)*((Math.random()*2)|0);



Como se ve, este puerto devolvería un valor entre 3 y 6, pero a veces, de forma aleatoria, devolvería 0. Al leer ese puerto, la mayoría de veces me ha devuelto 5 y 8, pero casi siempre solo 5, así que elegí un valor variable que estuviera cerca de ese valor, y este resultado es muchísimo mejor que simplemente devolver aleatoriamente un valor entre 0 y 255, por lo menos para este demo de fuego particular.

Incluso emuladores como Bochs tienen problemas, y por lo menos la última vez que corrí ese mismo demo usando Bochs 2.3.7, la forma en la que se ve en mi emulador es mucho mejor que en Bochs, así que este es un gran comienzo, que ha dejado todas estas lecciones, y que seguramente será más emocionante a medida que este emulador de x86 en HTML5 vaya quedando cada vez más completo.

Además, en una PC real, las siguientes 3 líneas de Ensamblador son necesarias para que las llamas sean suficientemente altas, pero en un emulador como este o como Bochs, son el primer problema que hace que las llamas se vean más borrosas que definidas (para el emulador es mejor mantenerlas comentadas como se muestra, pero para una PC real es mejor quitar los comentarios borrando la comilla al inicio de la línea; solucionar esto en un emulador es potencialmente algo extremadamente difícil de lograr):

Código: Seleccionar todo
;   xor     al,[di+bx]   ; more random
;      and     al,11b          ; mod 4
;      mov     dl,68           ;68  164



Se ve algo borroso como lo siguiente, aunque es muy posible que haya errores en algunas instrucciones o componentes de video que se han implementado, y por eso se acentúen las diferencias (en ese caso no hay más opción que corregir cada error):

jansflame
Imagen
IP for hosts file (email udocproject@yahoo.com to get updates if website becomes offline):
Código: Seleccionar todo
190.150.9.244 archefire.org



See what I'm doing in real time:
Main Desktop 1
Main Desktop 2
Avatar de Usuario
~
Site Admin
 
Mensajes: 2958
Registrado: Sab Nov 10, 2012 1:04 pm

Re: Emulador de PC, VGA y el Resto de Periféricos

Notapor ~ » Lun Jul 15, 2013 5:13 pm

Ahora necesito implementar la funcionalidad del modo 12h de la VGA, 640x480x16 colores.

Lo primero que necesito es ir en orden. Veo que desde aquí necesito documentar todos los registros estándar que son utilizables en cada modo para generalizar las funciones de forma realmente dinámica más que con funciones para cada modo estático y hasta ahora poco configurable en realidad.

Hablando específicamente del modo 12h a implementar, lo primero que necesito hacer es agregar código para redimensionar el Canvas y el overscan emulados al recibir la petición de la INT 10h. Esto implica que tendré que agregar código de redimensionamiento para cada modo gráfico existente en el emulador.
Imagen
IP for hosts file (email udocproject@yahoo.com to get updates if website becomes offline):
Código: Seleccionar todo
190.150.9.244 archefire.org



See what I'm doing in real time:
Main Desktop 1
Main Desktop 2
Avatar de Usuario
~
Site Admin
 
Mensajes: 2958
Registrado: Sab Nov 10, 2012 1:04 pm

Re: Emulador de PC, VGA y el Resto de Periféricos

Notapor ~ » Lun Jul 15, 2013 5:58 pm

Ahora tuve que implementar las siguientes instrucciones para ganar la capacidad de correr el siguiente demo para el modo VGA 12h 640x480x16 colores:

push imm16 (opcode 0x68)
and r/m8,imm8 (opcode 0x80 /4)

Código: Seleccionar todo
bits 16
org 100h


START:

mov ax,12h
int 10h




push word 0xA000
push word 0xA000
pop ds
pop es

xor si,si
xor di,di
xor ax,ax
xor bx,bx


mov cx,65535
mov dx,0x3C4
mov al,2

.ll:

;INIT: Clean up graphics memory
;INIT: Clean up graphics memory
;INIT: Clean up graphics memory
;INIT: Clean up graphics memory

push ax
push di

;Enable all planes:
;;
 mov ah,15
 out dx,ax

;Set a value of 0
;;
 mov al,0

;Write it:
;;
 stosb


pop di
pop ax


;END:  Clean up graphics memory
;END:  Clean up graphics memory
;END:  Clean up graphics memory
;END:  Clean up graphics memory



out dx,ax


inc ah
and ah,1111b


push ax
mov al,bl
inc bl
stosb

pop ax


dec cx
jnz .ll


cli
hlt

align 16


Imagen
IP for hosts file (email udocproject@yahoo.com to get updates if website becomes offline):
Código: Seleccionar todo
190.150.9.244 archefire.org



See what I'm doing in real time:
Main Desktop 1
Main Desktop 2
Avatar de Usuario
~
Site Admin
 
Mensajes: 2958
Registrado: Sab Nov 10, 2012 1:04 pm

Re: Emulador de PC, VGA y el Resto de Periféricos

Notapor ~ » Lun Jul 15, 2013 6:41 pm

Ahora necesito implementar la función de generación de pixeles para el modo 640x480x16 colores.

Primero tuve que crear una función esqueleto para escribir la memoria de video en el modo 12h, y esta a su vez llama a la función que genera los pixeles (8 pixeles por byte). Esta es la primera función que necesita hacer uso de más registros de la VGA, principalmente el Registro de Máscara de Mapa (Map Mask Register).

Esta también es la primera función generadora de pixeles que escribe por sí misma la memoria de video para cada plano activo y después, siempre y cuando la memoria de video esté en el rango visible, procede a dibujar los pixeles.
Imagen
IP for hosts file (email udocproject@yahoo.com to get updates if website becomes offline):
Código: Seleccionar todo
190.150.9.244 archefire.org



See what I'm doing in real time:
Main Desktop 1
Main Desktop 2
Avatar de Usuario
~
Site Admin
 
Mensajes: 2958
Registrado: Sab Nov 10, 2012 1:04 pm

Re: Emulador de PC, VGA y el Resto de Periféricos

Notapor ~ » Mié Jul 24, 2013 10:06 am

Este es el resultado del programa anterior siendo emulado que, por lo menos en lo que respecta a lo más básico, funciona de forma idéntica en una PC real y en el emulador:

Modo 12h básico
Imagen
IP for hosts file (email udocproject@yahoo.com to get updates if website becomes offline):
Código: Seleccionar todo
190.150.9.244 archefire.org



See what I'm doing in real time:
Main Desktop 1
Main Desktop 2
Avatar de Usuario
~
Site Admin
 
Mensajes: 2958
Registrado: Sab Nov 10, 2012 1:04 pm

Re: Emulador de PC, VGA y el Resto de Periféricos

Notapor ~ » Mié Jul 24, 2013 11:58 pm

He agregado los archivos PLANE1.DAT y PLANE2.DAT del demo WAVES.ZIP para el modo VGA 12h 640x480x16, a una imagen temporal de ROM, que va desde 0xC8000, dado que no pude comprimir los datos a un nivel decente, y el hecho de que me urge seguir implementando características de la VGA e instrucciones emuladas.

Lo que ahora necesito hacer es, antes de todo esto, crear un demo del modo 12h que modifique la paleta de 16 colores, y que igual que en otros modos gráficos, actualicen automáticamente los colores en pantalla.
Imagen
IP for hosts file (email udocproject@yahoo.com to get updates if website becomes offline):
Código: Seleccionar todo
190.150.9.244 archefire.org



See what I'm doing in real time:
Main Desktop 1
Main Desktop 2
Avatar de Usuario
~
Site Admin
 
Mensajes: 2958
Registrado: Sab Nov 10, 2012 1:04 pm

Re: Emulador de PC, VGA y el Resto de Periféricos

Notapor ~ » Jue Jul 25, 2013 12:05 am

Recordemos que la paleta de 16 colores está en el Controlador de Atributos, y este es el controlador que necesita resetear su Flip/Flop para asegurarse de que la primera escritura siempre comience accediendo el registro d índice de dicho controlador.

Código: Seleccionar todo
;Reset flip-flop:
;;
 mov dx,0x3DA
 in al,dx


;Write index and data
;of attribute register:
;;
 mov al,0x20&0  ;;Index and keep bit 5 set to 1 for normal screen operation
 mov ah,0       ;;Value
 mov dx,0x3C0
 out dx,ax

Imagen
IP for hosts file (email udocproject@yahoo.com to get updates if website becomes offline):
Código: Seleccionar todo
190.150.9.244 archefire.org



See what I'm doing in real time:
Main Desktop 1
Main Desktop 2
Avatar de Usuario
~
Site Admin
 
Mensajes: 2958
Registrado: Sab Nov 10, 2012 1:04 pm

Re: Emulador de PC, VGA y el Resto de Periféricos

Notapor ~ » Jue Jul 25, 2013 12:36 am

He agregado código para los registros 0-15 de la paleta de 16 colores en el registro de atributos, para indicar que esta paleta ha sido alterada y que es necesario refrescar el contenido de color mostrado en la pantalla.
Imagen
IP for hosts file (email udocproject@yahoo.com to get updates if website becomes offline):
Código: Seleccionar todo
190.150.9.244 archefire.org



See what I'm doing in real time:
Main Desktop 1
Main Desktop 2
Avatar de Usuario
~
Site Admin
 
Mensajes: 2958
Registrado: Sab Nov 10, 2012 1:04 pm

Re: Emulador de PC, VGA y el Resto de Periféricos

Notapor ~ » Jue Jul 25, 2013 1:03 pm

Traté de agregar un refrescado dinámico para la paleta, pero este funciona mal porque la función predeterminada para escribir la memoria en el modo 12h (y tal vez modos de 16 e incluso 4 colores en general) no están preparadas para refrescar la memoria sin cambiar los planos.

Así que parece que voy a tener que crear una función aparte particularmente creada para refrescar la pantalla sin necesidad de modificar registros.
Imagen
IP for hosts file (email udocproject@yahoo.com to get updates if website becomes offline):
Código: Seleccionar todo
190.150.9.244 archefire.org



See what I'm doing in real time:
Main Desktop 1
Main Desktop 2
Avatar de Usuario
~
Site Admin
 
Mensajes: 2958
Registrado: Sab Nov 10, 2012 1:04 pm

Re: Emulador de PC, VGA y el Resto de Periféricos

Notapor ~ » Jue Jul 25, 2013 4:08 pm

El siguiente es el código de prueba para iterar sobre los 64 colores posibles (de los que solo son visibles 16 a la vez).

En el lado del emulador necesito implementar la funcionalidad que permita que apagar la pantalla con el bit 5 del registro de índice del controlador de atributos se tarde lo suficiente como para que no se note normalmente su apagado mientras se cambia la paleta, pero que su encendido sea inmediato.

También necesito implementar una función temporizada para actualizar los colores de la paleta en pantalla.

Código: Seleccionar todo
    bits 16
    org 100h


    START:

    mov ax,12h
    int 10h




    push word 0xA000
    push word 0xA000
    pop ds
    pop es

    xor si,si
    xor di,di
    xor ax,ax
    xor bx,bx


    mov cx,65535
    mov dx,0x3C4
    mov al,2

    .ll:

    ;INIT: Clean up graphics memory
    ;INIT: Clean up graphics memory
    ;INIT: Clean up graphics memory
    ;INIT: Clean up graphics memory

    push ax
    push di

    ;Enable all planes:
    ;;
     mov ah,15
     out dx,ax

    ;Set a value of 0
    ;;
     mov al,0

    ;Write it:
    ;;
     stosb


    pop di
    pop ax


    ;END:  Clean up graphics memory
    ;END:  Clean up graphics memory
    ;END:  Clean up graphics memory
    ;END:  Clean up graphics memory



    out dx,ax


    inc ah
    and ah,1111b


    push ax
    mov al,bl
    inc bl
    stosb

    pop ax


    dec cx
    jnz .ll



xor ax,ax
.pl:


 ;;INIT: Comment out keyboard press wait for incomplete BIOS/PC emulation test
 ;;INIT: Comment out keyboard press wait for incomplete BIOS/PC emulation test
 ;;INIT: Comment out keyboard press wait for incomplete BIOS/PC emulation test
 ;;INIT: Comment out keyboard press wait for incomplete BIOS/PC emulation test
;  push ax
;
;   xor ax,ax
;   int 16h
;
;  pop ax

 ;;END:  Comment out keyboard press wait for incomplete BIOS/PC emulation test
 ;;END:  Comment out keyboard press wait for incomplete BIOS/PC emulation test
 ;;END:  Comment out keyboard press wait for incomplete BIOS/PC emulation test
 ;;END:  Comment out keyboard press wait for incomplete BIOS/PC emulation test


 call pal16_write

 inc al
 and al,1111b


jmp .pl






    cli
    hlt



;AL == Register index
;;
pal16_write:
 push ax
 push bx
 push dx

  ;Reset flip-flop:
  ;;
   mov dx,0x3DA
   push ax
    in al,dx
   pop ax


  ;Write index and data
  ;of attribute register:
  ;;
   mov dx,0x3C0
;   or al,0x20     ;;Index and keep bit 5 set to 1 for normal screen operation
   out dx,al

   mov dx,0x3C1
   push ax
   in al,dx      ;;Read and
   mov ah,al     ;;put the value in AH instead of AL (which is the index)
   pop bx
   mov al,bl     ;;Restore AL
   

   inc ah         ;;increase the value
   and ah,111111b ;;Only allow bits 0-5
;   mov ah,0
   


  ;Reset flip-flop:
  ;;
   mov dx,0x3DA
   push ax
    in al,dx
   pop ax

  ;Write the increased value:
  ;;
   mov dx,0x3C0
   out dx,ax
;   out dx,al
;   mov al,ah
;   out dx,al


  ;Reset flip-flop:
  ;;
   mov dx,0x3DA
   push ax
    in al,dx
   pop ax


  mov dx,0x3C0
  mov al,0x20     ;;Index and keep bit 5 set to 1 for normal screen operation
  out dx,al

 pop dx
 pop bx
 pop ax
ret




    align 16



Afortunadamente todas las instrucciones requeridas por este programa parecen estar implementadas correctamente, por lo menos para este programa particular.
Imagen
IP for hosts file (email udocproject@yahoo.com to get updates if website becomes offline):
Código: Seleccionar todo
190.150.9.244 archefire.org



See what I'm doing in real time:
Main Desktop 1
Main Desktop 2
Avatar de Usuario
~
Site Admin
 
Mensajes: 2958
Registrado: Sab Nov 10, 2012 1:04 pm

Re: Emulador de PC, VGA y el Resto de Periféricos

Notapor ~ » Jue Jul 25, 2013 4:26 pm

Ya implementé el retardo para evitar que la pantalla emulada se "apague" constantemente y no pueda tener acceso al color.

Lo que ahora me hace falta es implementar la función para refrescar los colores dinámicamente al alterar las paletas de color.

Para esto necesito una función que me permita leer incondicionalmente los 4 planos para obtener los colores de 4 bits, y luego escribirlos en pantalla.
Imagen
IP for hosts file (email udocproject@yahoo.com to get updates if website becomes offline):
Código: Seleccionar todo
190.150.9.244 archefire.org



See what I'm doing in real time:
Main Desktop 1
Main Desktop 2
Avatar de Usuario
~
Site Admin
 
Mensajes: 2958
Registrado: Sab Nov 10, 2012 1:04 pm

Re: Emulador de PC, VGA y el Resto de Periféricos

Notapor ~ » Jue Jul 25, 2013 6:17 pm

Ya logré implementar la emulación de la modificación dinámica de los colores al cambiar las paletas, y esto específicamente para el modo 640x480x16 colores.

Ahora parece que tengo todo listo, a excepción de algunas instrucciones, y también de la implementación de prefijos de operadores para cambiar los registros de propósito general de 16 a 32 bits, para comenzar a probar correr el programa de WAVES.ZIP, que como dije anteriormente es un demo para el modo VGA 12h enfocado en los planos de color con ondas semitransparentes.

Más allá de eso, me hace falta actualizar el color del overscan tan pronto como se alteren esas paletas de color también.
Imagen
IP for hosts file (email udocproject@yahoo.com to get updates if website becomes offline):
Código: Seleccionar todo
190.150.9.244 archefire.org



See what I'm doing in real time:
Main Desktop 1
Main Desktop 2
Avatar de Usuario
~
Site Admin
 
Mensajes: 2958
Registrado: Sab Nov 10, 2012 1:04 pm

Re: Emulador de PC, VGA y el Resto de Periféricos

Notapor ~ » Jue Jul 25, 2013 6:38 pm

Ya logré implementar la actualización del overscan, tanto para la función general como para la actualización dinámica en el modo VGA 12h al cambiar la paleta de 16 o 256 colores.

Lo siguiente que voy a hacer es comenzar a ajustar o reimplementar el código del programa de WAVES.ZIP, para comenzar por modificar la paleta original, y luego, mostrar los archivos gráficos PLANE1.DAT y PLANE2.DAT, que por ahora están contenidos en el área de ROM que comienza desde 0xC8000.
Imagen
IP for hosts file (email udocproject@yahoo.com to get updates if website becomes offline):
Código: Seleccionar todo
190.150.9.244 archefire.org



See what I'm doing in real time:
Main Desktop 1
Main Desktop 2
Avatar de Usuario
~
Site Admin
 
Mensajes: 2958
Registrado: Sab Nov 10, 2012 1:04 pm

Re: Emulador de PC, VGA y el Resto de Periféricos

Notapor ~ » Jue Jul 25, 2013 8:28 pm

He logrado correr la parte más básica del programa de WAVES.ZIP, pero que es suficiente para demostrar que definitivamente está bien implementada la funcionalidad básica de los planos, e igualmente la funcionalidad de actualización de las paletas de 16 y 256 colores, bajo el modo VGA 12h, de 640x480x16 colores:

ZIP Z86Emu_v2013-07-25.zip
Muestra de WAVES.ZIP escribiendo en los planos 0 y 1


En este punto, tengo la opción seguir completando ese programa (completando opcodes adicionales también), seguir agregando periféricos, agregar llamadas de servicio de interrupción correspondientes al BIOS o el DOS (todas integradas en nuestro BIOS, y nuestro "DOS on BIOS").
Imagen
IP for hosts file (email udocproject@yahoo.com to get updates if website becomes offline):
Código: Seleccionar todo
190.150.9.244 archefire.org



See what I'm doing in real time:
Main Desktop 1
Main Desktop 2
Avatar de Usuario
~
Site Admin
 
Mensajes: 2958
Registrado: Sab Nov 10, 2012 1:04 pm

Re: Emulador de PC, VGA y el Resto de Periféricos

Notapor ~ » Vie Jul 26, 2013 10:25 am

He creado un punto de respaldo aquí, así que ahora podemos modificar de forma indiscriminada nuevas características temporales de prueba a nuestro emulador sin temor a destruir nuestro avance actual, y con la posibilidad de volver a este punto de respaldo total o parcialmente:

ZIP Z86Emu_v2013-07-26-10-21.zip
Imagen
IP for hosts file (email udocproject@yahoo.com to get updates if website becomes offline):
Código: Seleccionar todo
190.150.9.244 archefire.org



See what I'm doing in real time:
Main Desktop 1
Main Desktop 2
Avatar de Usuario
~
Site Admin
 
Mensajes: 2958
Registrado: Sab Nov 10, 2012 1:04 pm

Re: Emulador de PC, VGA y el Resto de Periféricos

Notapor ~ » Vie Jul 26, 2013 8:01 pm

En este momento necesito implementar muchas instrucciones adicionales en masa, y necesito depurar dichas instrucciones para determinar sus resultados y compararlos con los de mi emulador.

Ya que la versión de DEBUG.COM que trae Windows no funciona para instrucciones extendidas (que comienzan por ejemplo con un byte 0x0F), tales como MOVSX, tuve que buscar otro depurador.

Afortunadamente la versión de DEBUG.COM que viene con FreeDOS sí reconoce estas instrucciones extendidas, así que esta es la que voy a usar:

ZIP debug126-new.zip
Imagen
IP for hosts file (email udocproject@yahoo.com to get updates if website becomes offline):
Código: Seleccionar todo
190.150.9.244 archefire.org



See what I'm doing in real time:
Main Desktop 1
Main Desktop 2
Avatar de Usuario
~
Site Admin
 
Mensajes: 2958
Registrado: Sab Nov 10, 2012 1:04 pm

Re: Emulador de PC, VGA y el Resto de Periféricos

Notapor ~ » Vie Jul 26, 2013 8:25 pm

Ahora que he implementado la funcionalidad para MOVSX r16,r/m8, y ya que he implementado muchas variedades de funcionalidades para el byte ModR/M, tanto para la lectura y escritura de registros y memoria también, lo que necesito hacer ahora es implementar TODAS las funcionalidades faltantes.

Y para esto voy a comenzar por hacer una lista de TODAS las funciones no definidas, que deberé implementar a continuación:
ModRM para 16 bits

CPU_ModRM_Common16_BX_SI__W
CPU_ModRM_Common16_BP_SI__W
CPU_ModRM_Common16_BP_DI__W
CPU_ModRM_Common16_SI__W

CPU_ModRM_Common16_BX_SI_disp8__W
CPU_ModRM_Common16_BX_DI_disp8__W
CPU_ModRM_Common16_BP_SI_disp8__W
CPU_ModRM_Common16_BP_DI_disp8__W
CPU_ModRM_Common16_SI_disp8__W
CPU_ModRM_Common16_BP_disp8__W
CPU_ModRM_Common16_BX_disp8__W

CPU_ModRM_Common16_BX_SI_disp16__W
CPU_ModRM_Common16_BX_DI_disp16__W
CPU_ModRM_Common16_BP_SI_disp16__W
CPU_ModRM_Common16_BP_DI_disp16__W
CPU_ModRM_Common16_BP_disp16__W
CPU_ModRM_Common16_BX_disp16__W




CPU_ModRM_Common16_BX_SI_disp8__R
CPU_ModRM_Common16_BX_DI_disp8__R
CPU_ModRM_Common16_BP_SI_disp8__R
CPU_ModRM_Common16_BP_DI_disp8__R
CPU_ModRM_Common16_SI_disp8__R
CPU_ModRM_Common16_BP_disp8__R
CPU_ModRM_Common16_BX_disp8__R

CPU_ModRM_Common16_BX_SI_disp16__R
CPU_ModRM_Common16_BX_DI_disp16__R
CPU_ModRM_Common16_BP_SI_disp16__R
CPU_ModRM_Common16_BP_DI_disp16__R
CPU_ModRM_Common16_SI_disp16__R
CPU_ModRM_Common16_BP_disp16__R
CPU_ModRM_Common16_BX_disp16__R
Imagen
IP for hosts file (email udocproject@yahoo.com to get updates if website becomes offline):
Código: Seleccionar todo
190.150.9.244 archefire.org



See what I'm doing in real time:
Main Desktop 1
Main Desktop 2
Avatar de Usuario
~
Site Admin
 
Mensajes: 2958
Registrado: Sab Nov 10, 2012 1:04 pm

Re: Emulador de PC, VGA y el Resto de Periféricos

Notapor ~ » Sab Jul 27, 2013 11:17 am

He completado la implementación de toda la funcionalidad de lectura y escritura para el byte ModR/M para código de 16 bits, lo que significa que ahora todas las instrucciones que necesiten esto están totalmente capacitadas para acceder cualquier índice que se les presente.

Lo siguiente que debería hacer para completar esta funcionalidad probablemente debería ser implementar la instrucción LEA, y luego pasar a otras instrucciones o funciones de otros periféricos (entre el video y el teclado, para continuar).
Imagen
IP for hosts file (email udocproject@yahoo.com to get updates if website becomes offline):
Código: Seleccionar todo
190.150.9.244 archefire.org



See what I'm doing in real time:
Main Desktop 1
Main Desktop 2
Avatar de Usuario
~
Site Admin
 
Mensajes: 2958
Registrado: Sab Nov 10, 2012 1:04 pm

Re: Emulador de PC, VGA y el Resto de Periféricos

Notapor ~ » Sab Jul 27, 2013 12:46 pm

Ya implementé la instrucción LEA y la funcionalidad para el byte ModR/M de la que esta depende (ambas de 16 bits), así que puedo considerar completamente implementada la funcionalodad para código de 16 bits del byte ModR/M.
Imagen
IP for hosts file (email udocproject@yahoo.com to get updates if website becomes offline):
Código: Seleccionar todo
190.150.9.244 archefire.org



See what I'm doing in real time:
Main Desktop 1
Main Desktop 2
Avatar de Usuario
~
Site Admin
 
Mensajes: 2958
Registrado: Sab Nov 10, 2012 1:04 pm

Re: Emulador de PC, VGA y el Resto de Periféricos

Notapor ~ » Sab Jul 27, 2013 1:00 pm

He completado la funcionalidad central más básica de la instrucción que corresponde a la función CPU_Opcode16_0xF7_04__mul_r_m16, así que ya puedo hacer multiplicaciones básicas entre AX y un registro de propósito general o memoria de 16 bits, y devolver el resultado en DX:AX.
Imagen
IP for hosts file (email udocproject@yahoo.com to get updates if website becomes offline):
Código: Seleccionar todo
190.150.9.244 archefire.org



See what I'm doing in real time:
Main Desktop 1
Main Desktop 2
Avatar de Usuario
~
Site Admin
 
Mensajes: 2958
Registrado: Sab Nov 10, 2012 1:04 pm

Re: Emulador de PC, VGA y el Resto de Periféricos

Notapor ~ » Dom Jul 28, 2013 1:34 pm

En este momento estoy tratando de comenzar a agregar mucho del soporte necesario para acceder dinámicamente datos de memoria y registros de 32 bits.

Ya que todo estaba bien adaptado para 16 bits, se me hace difícil determinar cómo hacer esto, pero estoy comenzando por agregar funciones específicas para leer los registros de 32 bits, y también estudiando cómo agregar y compatibilizar las tablas del byte ModR/M para 16 y 32 bits.

Seguramente este es el momento más adecuado para agregar soporte de 32 bits con un mínimo de espacio para poder extender a un modo protegido, ahora que tengo suficientes instrucciones como para probar diferente código, pero no tantas como para hacer imposiblemente tediosa la actualización de estas para datos de 32 bits.
Imagen
IP for hosts file (email udocproject@yahoo.com to get updates if website becomes offline):
Código: Seleccionar todo
190.150.9.244 archefire.org



See what I'm doing in real time:
Main Desktop 1
Main Desktop 2
Avatar de Usuario
~
Site Admin
 
Mensajes: 2958
Registrado: Sab Nov 10, 2012 1:04 pm

Re: Emulador de PC, VGA y el Resto de Periféricos

Notapor ~ » Dom Jul 28, 2013 2:08 pm

Después de agregar más soporte a la funcionalidad de ModR/M, veo que el prefijo de operandos 0x66 solamente afecta al tamaño de los operadores.

Pero lo que afecta y dicta qué tabla del byte ModR/M usar en el código (la de 16 bits, totalmente implementada, o la de 32 bits, sin implementar), es el prefijo de direccionamiento (addressing override, 0x67 o el mnemónico a32).

Así que mientras no usemos este prefijo de direccionamiento 0x67, podemos seguir usando sin problema la tabla de direccionamiento de 16 bits para el byte ModR/M, y lo único que cambiará es el efecto en el que escribiremos 4 bytes en lugar de 2 bytes.

Sin embargo, esto solo es útil para algunas instrucciones (las que usan 1 byte siempre por ejemplo no deberían afectarse); así que tendremos que ser muy cuidadosos ahora que una de nuestras tareas adicionales es agregar soporte para datos y registros de 32 bits (que voy a agregar poco apoco, y estrictamente cuando un programa de prueba, como el caso de WAVES.ZIP, lo demande).
Imagen
IP for hosts file (email udocproject@yahoo.com to get updates if website becomes offline):
Código: Seleccionar todo
190.150.9.244 archefire.org



See what I'm doing in real time:
Main Desktop 1
Main Desktop 2
Avatar de Usuario
~
Site Admin
 
Mensajes: 2958
Registrado: Sab Nov 10, 2012 1:04 pm

Siguiente

Volver a IBM PC y Compatibles

¿Quién está conectado?

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


cron