Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Mensajes - Serapis

#2311
Es que el tema resulta trivial...

Sea el caso del procesador 8086, el bus de datos es de 16bits, en tanto que el bus de direcciones es de 20bits.
Mientras que 16 bits direccionan 65.536 posiciones de memoria, 4 bits más (es decir 20bits), direccionan 1Mb.
Si divides 1Mb. entre los 64kb. tienes 16, que son el número de páginas que tiene 1Mb. 16 páginas son precisamente los valores que codifican 4bits.

Asi a las direcciones se les antepone el código de página:

pagina: Dirección16bits    
0000:0000.0000-0000.0000
Y ya con los 20 bits se obtiene la dirección absoluta.
La dirección de 16bits, es relativa en la página, es decir, va desde 0 hasta 65.535.
Pongamos que la página es la 5 y pongamos que la dirección en la pagina es 22.222,
la dirección real se calcula como::
nºpagina x 65.536 + direccion relativa
Y que por tanto, para el jemplo será:
5*65.536 + 22.222 = 327.680 + 22.222 = 349.902
Igualmente puede ponerse en binario (por ejemplo en la calculadora) y luego pasarlo a decimal
página 5: Dir relativa; 22.222
0101:0101.0110-1100.1110 = 349.902

Esto sería como tener un mazo de 16 cartas, donde cada una de ellas representara 64kb.
Esto de más arriba, sin embargo es la explicación ideal...
...es decir la entrada para poder empezar a entender como es realmente.

A la página se le llama segmento y a la dirección relativa, desplazamiento..
Puesto que los registros en el 8086, son de 16 bits, incluído el registro IP.
La solución adoptada, aunque ingeniosa estuvo limitando la accesibilidad a la memoria, dejando en hándicap al PC frente a otros procesadores... y así se crearon los llamados registros de segmento.
La dirección física se compone realmente de dos registros:
El de segmento, y uno de propósito general que formaliza el 'offset' (desplazmaiento dentro del segmento).
En la explicación ideal, si se mira bien, si se repara lo suficiente, presenta un problema y es que como toma 64kb.
exige que un bloque de un programa tenga que coincidir alojado exactamente en un segmento. Es decir resulta un problema si parte de un programa cae en un bloque y parte en otro, pués un único segmento no basta para acceder al programa.
Aprovechando que también los registros de segmento eran igualmente de 16 bits, se eligió otro modelo, y es el que explico a continuación:
El de segmento queda desplazado 4 posiciones hacia arriba (es como si fuera de 20,  donde los 4 bits de menor peso estuvieren a 0), pero naturalmente el resto de los bits de ese registro pueden tener un valor arbitrario (no solo los 4 bits de menor peso).
Esto permite que pueda ubicarse en cualquier punto de la memoria (congruente con 16) el comienzo del bloque de 64kb.
Pero ahora en vez de haber 16 páginas de 64kb. ahora hay 64k.páginas de 16 bytes.
Esto permite que haya muchos pares segmento:desplazamiento (4096 exactamente, 65536/16=4096) que apunten a una misma dirección de memoria.

Ejemplo:
A - Registro de segmento:  
1000.0010-0011.0101 = 33.333
1000.0010-0011.0101*16= 533.328
1000.0010-0011.0101-0000 nótese el desplazamiento a la izquierda de 4 bits.

B - desplazamiento:
0101.0110-1100.1110 =  22.222

C - Dirección física: 533.328 + 22.222 = 555.550

1000.0010-0011.0101-0000
------0101.0110-1100.1110
-----------------------------------
1000-0111.1010-0001.1110 = 555.550

Haz si quieres las cuentas en hexadecinal que cada nibble es una cifra, y se ve mejor...

Y si lo has seguido hasta aquí, te invito a que pongas los bits altos del registro de segmento a 1 y verifiques a qué dirección de memoria estaríamos accediendo???
Por lo demás el cálculo real sigue siendo el explicado en el razonamiento ideal...

En fin, no hace falta mucho código, simplemente un array y un par de 'registros'... y alguna funcionalidad de lectura y/o escritura...

Envió antes que caduque la sesión y me edito luego... con algo de código de ejemplo.

Código (vb) [Seleccionar]

' El integer de VB6 no es 'unsigned', así que lo emulamos...
Private Type UInteger
   Bajo        As Byte     ' bits 0-7   ' podría acederse de este modo fácilmente a AH y AL, etc...
   Alto        As Byte     ' bits 8-15
End Type


Private Const c_MegaByte = (2 ^ 20)                         ' 1Mb.
Private Const c_Pagina = (2 ^ 16)                           ' 64Kb.

' 1Mb. de memoria.
Private s_Memoria(0 To c_MegaByte - 1) As Byte


Private s_DirFisica             As Long

Private p_RegAX                 As UInteger  ' registros de 16 bits.
Private p_RegIP                 As UInteger
Private p_RegCS                 As UInteger



Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)



Private Property Get Segmento() As UInteger
    Segmento = p_RegCS
End Property
   Private Property Let Segmento(ByRef X As UInteger)
       p_RegCS = X
       Call CalculaDireccionFisica
   End Property

Private Property Get IP() As UInteger
    IP = p_RegIP
End Property
   Private Property Let IP(ByRef X As UInteger)
       p_RegIP = X
       Call CalculaDireccionFisica
   End Property

Private Property Get AX() As UInteger
    AX = p_RegAX
End Property
   Private Property Let AX(ByRef X As UInteger)
       p_RegAX = X
   End Property

Private Property Get DireccionFisica() As Long
   DireccionFisica = s_DirFisica
End Property


Private Sub CalculaDireccionFisica()
   Dim X As Long
   
   s_DirFisica = 0 ' al tener 4 bytes, primero los borramos todos...
   Call CopyMemory(s_DirFisica, ByVal VarPtr(p_RegCS), 2)
   Call CopyMemory(X, ByVal VarPtr(p_RegIP), 2)
   s_DirFisica = ((s_DirFisica * 16) + X)
End Sub


Private Function StringToUInteger(ByRef Txt As String) As UInteger
   Dim v As UInteger
   Dim k As Long
   
   k = Val(Txt)
   v.Bajo = (k And 255)
   v.Alto = (k \ 256)
   
   StringToUInteger = v
End Function



Private Sub Command1_Click()
   Segmento = StringToUInteger(Text1.Text)
   IP = StringToUInteger(Text2.Text)
   
   Text3.Text = DireccionFisica
End Sub

Private Sub Command2_Click()
   Dim v As UInteger
   
   AX = StringToUInteger(Text4.Text)
   
   s_Memoria(s_DirFisica) = AX.Bajo
   s_Memoria(s_DirFisica + 1) = AX.Alto
End Sub


Añade 3 textbox, con sendos labels, el textbox1 será el de 'segmento' y sí poner en el label, eñ textbox 2, será el desplazamiento, para el eejemplo la dirección IP, el tercer textbox, la dirección física.
Añade un bótón, introduce de entrada los valores de más arriba que puse d eejmplo: Segmento: 33.333 y desplazamiento 22.222, y a la vuelta en el textbox 3 tendrás el valor de la dirección física real.

Usa ese valor como índice en el array s_Memoria...

Solo resta indicar que si bien la memoria del 8086 son direcciones de 16bits... y el array está declarado en bytes... debemos acceder individualmente a cada byte (como señala el código dle 2º botón, o bien usar copymemory).

Añade un segundo boitón y un 4º textbox... con su label 'Valor', introduce un valor en el rango 0-65535 en el textbox4, y pulsa el botón 2, escribirá en la memoria dicho valor...

Puedes si quieres al iniciar el formulario, relenar con valores al azar el array y añadir un botón para leer de la memoria actual, el valor que contiene...
Podrías también añadir un avance del registro IP en 2 posiciones ...

En fin, como has sido parco en palabras, no he podido orientar el código convenientemente... si tratas de hacer algún emulador, ya tienes por donde tomarlo...
#2312
¿Puedes indicar que necesitas más en específico?
#2313
Sí...

...a este paso, en 10 años tendremos la "I Guerra Mundial De Internet"...
#2315
Ok... sí, no había leído bien.

De todos modos también tiene fácil solución...
Al guardar la tarjeta, no lo hagams de cualquier manera... una cartera adecuada al caso, debe estar apantallada al menos con una 'hoja' de aluminio... Recortamos una chapa de aluminio del mismo tamaño que una tarjeta de crédito, y la ponemos sobre uno de los extremos de la cartea haciendo de forro, mejor si es en ambas partes, así no hay que andar pensando si la tarjeta la pusiste boca arriba o boca abajo. Algo sencillo y barato...

En realidad deberían vender a estas alturas carteras 'blindadas' de esta manera.
#2316
mmm... los móviles vienen con opción de desactivar el chip NFC, lo mismo que el wifi.

Luego lo correcto es tenerlo desactivado de forma constante y solo activarlo al ir a pagar y tras el pago, volvelro a desactivar.
#2317
Dudas Generales / Re: duda viaje
22 Julio 2018, 22:12 PM
Esto es dependiente básicamente del país, no existen leyes internacionales unificadas al respecto.

En USA, cada vez lo ponen peor al menos para entrar, tanto como revisar el contenido de CDs, no, pero si resultares sospechoso, quien sabe...probablemente si.?

En cuanto a revistas porno, depende mucho de la cultura. Si se trata de un país islámico (países mojigatos en general), quizás pueda verse como algo delictivo, o en el mejor de los casos, quien te lo revise, te lo requise (y se quede con ello para sí)... Es preferible al menos no entrar con material porno a un país, en todo caso al salir, es decir que lo has comprado ahí, y si es así, es porque resulta legal...

Todo ese material, si decides llevarlo, mucho mejor si lo llevas facturado, no como equipaje de mano. Y mejor aún si queda adecuadamente empaquetado, pero no hagas un paquete-matrioska, que acaba pareciendo sospechoso.
De todos modos al salir de un país, entras en otro, luego siempre se pasan dos controles, y aunque en uno fuera todo bien, quien sabe en el otro...
#2318
Hummmmm....
Pasan por el alto, que el sodio es incendiario con solo arrojarlo al agua...
Imagina las catástrofes que se podrían hacer con solo 150 'dolores', digo con una tonelada de sodio...
#2319
Foro Libre / Re: Gafas en Cine 3D
21 Julio 2018, 16:37 PM
No sabía que habína eliminaod al personal de venta de entradas... supongo que esto será en según que ciudades y quizás con el tiempo quierna aplicarlo a todos... (ya sabes se hace sigilosamente, despacio, para que dé tiempo a sumirlo o asimilarlo y no haya demasiadas quejas como sucedería si fuera 'de repente' en todas partes.

De todos modos, personal dentro tiene que haber... (si no que te impediría que al acabar una peli te fueras a otra sala, para ver otra peli de la siguiente sesión??) y las gafas suelen repartirlas justo dentro de la sala, antes de que te dirijas a tomar asiento y antes de que empiece la peli, si llegaras 15 minutos tarde, no estoy seguro si seguirá ahí la caja... y recogerlas justo delante de la puerta de salida...
#2320
.NET (C#, VB.NET, ASP) / Re: MenuStrip
21 Julio 2018, 15:45 PM
Al margen de que el código no es óptimo, no hay nada ilegal en él...

El comentario (siguiente, el tachado) es erróneo (aparece el constructor de clase, que pasé por alto). No obstante, tras su declaración la función llamada lo creará si lo precisa, luego sobra hacerlo aquí y por tanto basta su declaración: Dim submenu As ArrayList


(excepto que en esta línea declaraste un array de arraylist, y sobra como array, es decir elimina los paréntesis)
Dim submenu As New ArrayList()


Lo que sucede es que posiblemente no entiendas el formulario MDI.
Un formulari MDI, siempre subsume el menú,  del formulario hijo en su propio menú.
bueno siempre no... Esto está controlado por la propiedad AllowMerge del menustrip. (Abajo del todo, en la última sección, te pongo un ejemplo para dicho caso, son cambios ligeros)

Así cuando tú seleccionas Ventas, se crea el formulario con los menús asociados a él, y lo mismo con Compras... (o con alguno más si añadieras más), pero una vez que (por ejemplo) 'Ventas' tiene el foco, su menú se integra en el padre. A su vez el formulario hijo que pierde el foco (por ejemplo "Compras"), ve de vuelta su menú sobre sí, siendo retirado del formulario padre...

Una forma de verlo muy muy claro, es añadir el siguiente código al frmSubmenus
Haciendo que el formulario hijo ocupe toda el área cliente del formulario padre, no habría sitio para el menú del hijo...
Código (vbnet) [Seleccionar]
Private Sub frmSubmenus_GotFocus(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.GotFocus
       Me.WindowState = FormWindowState.Maximized
   End Sub


Y eso es todo...





A continuación, lo que te presento es algunas correciones...

En VB, no hay "BREAK", para los bloques de control "select case", luego las sentencias 'Exit select', sobran si ya se llegó al final del código del propio 'case'.
Tampoco tiene sentido llamar al araylist 'submenú... conforme a la función simplemente genera una lista, luego no tiene sentido darle un nombre más propio que lista. Tampoco es necesario asignarlo Nothing, si luego lo vas a crear...
de hecho el 'case else' sobra, y se pone solo por lo molesto del 'warning'... aunque el propio compilador ya detectaría que como de entrada es nothing, eso es lo que devuelve y que por tanto el warning, es absurdo...
Código (vbnet) [Seleccionar]

Public Function MenuSecundario(ByVal txt As String) As ArrayList
       Dim lista As ArrayList
       Select Case txt
           Case "Ventas"
               lista = New ArrayList
               lista.Add("Cotizacion")
               lista.Add("Pedidos")
               lista.Add("Clientes")
               lista.Add("por Autorizar")
               lista.Add("Calendario")
               lista.Add("Estadisticas")
           Case "Compras"
               lista = New ArrayList
               lista.Add("Pendientes")
               lista.Add("Administrador")
               lista.Add("Productos")
               lista.Add("Proveedores")
               lista.Add("Clientes")
               lista.Add("Calendario")
               lista.Add("Estadisticas")
           Case Else
               lista = Nothing
       End Select
       Return lista
   End Function


en el siguiente código hay 3 cosas que decir...
1- submenu es un objeto arraylist, la función llamada lo creará si lo precisa, luego sobra hacerlo aquí, basta su declaración.
2- El try...catch, carece de sentido, la línea "If Not IsNothing(submenu) Then" ya previene el posible error que pudiera ser generado, el recorrido de la lista como se hace con 'for each' no va a generar error', lo mismo que añadir ítems al menu... ahí el único error posible es que no existiera el menustrip1. Algo que se va a detectar en diseño, a poco que se pruebe el proyecto... luego poner try....catch, donde no son necesarios es una práctica lastrante.
3 - El msgbox, también sobra, aunque en diseño, para probar puedes ponerlo, de todas manearas unas décimas de segundo, después se podrá ver sobre la ventana MDI, luego...
Código (vbnet) [Seleccionar]

Private Sub frmSubMenus_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
       For Each ctr As Control In Me.Controls
           Me.ToolTip1.SetToolTip(ctr, ctr.ToString)
       Next
       'Try
       Dim submenu As ArrayList  
       submenu = MenuSecundario(Me.Text)
       If Not IsNothing(submenu) Then
           For Each str As String In submenu
               'MsgBox(str)
               MenuStrip1.Items.Add(str)
           Next
       End If
       'Catch ex As Exception
       'MsgBox("ERROR." + vbLf + ex.Message + vbLf + ex.ToString)
       'End Try
   End Sub


En esta sección, hemos movido la declaración del form al módulo de clase, fuera de la funcionalidad del evento.
El try...catch, también sobra, pero puedes mantenerlo mientras lo pruebas, antes de compilar, coméntal dichas líneas...
Lo más importante... como no has limitado de ninguna manera que pueda seguir creando más formularios 'Ventas, 'Compras'...cada vez que pulses en el menuStrip "Ventas", ó "Compras", generarás un nuevo formulario, cada uno con su propio menú, el problema es que no sabrás distinguir uno de otro...
Entonces o bien limitas a que solo se cree un único menú de cada tipo o bien 'personaliza el nombre' para cada uno...
La forma más simple de personalizar el nombre, es autonumerarlos... Es el código que añado sobre lo que tú tienes...
Código (vbnet) [Seleccionar]

Dim form As frmSubmenus

   Private Sub MenuStrip_ItemClicked(ByVal sender As System.Object, ByVal e As System.Windows.Forms.ToolStripItemClickedEventArgs) Handles MenuStrip.ItemClicked
       Static childrens As Int16
       Try
           form = New frmSubmenus
           form.MdiParent = Me
           form.Text = e.ClickedItem.Text & "-" & childrens.ToString
           form.Show()
           childrens += 1
       Catch ex As Exception
           MsgBox("ERROR." + ex.Message)
       End Try
   End Sub






p.d.: añado los cambios para que cada formulario porte su propio menú... de forma independiente.

Ahora si tu prefieres que cada menú hijo tenga su propio menú sobre sí, y no subsumido en el 'padre', tienes que hacer estos cambios:

Ve a las propiedades del formulario MDI, selecciona el objeto MenuStrip1, cambia su propiedad
AllowMerge del menustrip1 a FALSE

Y ahora cambia el código en cada formulario según el code de cada uno que pongo a continuación...

Código (vbnet) [Seleccionar]

Private Sub frmSubMenus_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
       Dim submenu As ArrayList

       For Each ctr As Control In Me.Controls
           Me.ToolTip1.SetToolTip(ctr, ctr.ToString)
       Next
   
       
       ' Como ahora el texto de cada formulario está autonemuerado (pero comenzando con un guión)
       ' Tomamos la parte común del nombre...
       ' Esto tendría más fácil solución si en vez de pasar un string, se pasara un valor numérico
       ' por ejemplo:   (1=Ventas, 2=compras, otro=else) partiendo quizás de una enumeración...
       Dim strName As String
       Dim k As Integer = InStr(Me.Text, "-")
       If (k > 0) Then
           strName = Me.Text.Substring(0, k - 1)
       Else
           strName = Me.Text
       End If

       submenu = MenuSecundario(strName)
       If Not IsNothing(submenu) Then
           For Each str As String In submenu              
               Me.MenuStrip1.Items.Add(str)
           Next        
       End If        
   End Sub


El autonumerado sigue válido para el caso, así verás más ventanas del mismo tipo cada una con su propio menú... (esto es copia del código del último bloque antes de la linea de sección).
Código (vbnet) [Seleccionar]

Dim form As frmSubmenus

   Private Sub MenuStrip_ItemClicked(ByVal sender As System.Object, ByVal e As System.Windows.Forms.ToolStripItemClickedEventArgs) Handles MenuStrip.ItemClicked
       Static childrens As Int16
       Try
           form = New frmSubmenus
           form.MdiParent = Me
           form.Text = e.ClickedItem.Text & "-" & childrens.ToString
           form.Show()
           childrens += 1
       Catch ex As Exception
           MsgBox("ERROR." + ex.Message)
       End Try
   End Sub


Y si tienes activado El windowSTate Maximized... tendrás otra línea de menú bajo el principal, prueba con y sin estas líneas...
Código (vbnet) [Seleccionar]
Private Sub frmSubmenus_GotFocus(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.GotFocus
       Me.WindowState = FormWindowState.Maximized
   End Sub







Aún así, debrrías limitar la creación de formularios, no es tolerable que cada vez que se pulse el menú, se cree una nueva ventana, porque durante una sesión un mismo menú podría ser pulsado 50 veces, crear 50 formularios... seguramente no sea necesario, creo que es algo que dejas abierto y no es adecuado.  Como mínimo habría que eliminar el formulario previo del mismo tipo...