variable resultado pantalla imprimir imprime como c x86 turbo-c real-mode

pantalla - como se imprime un resultado en c++



No se puede escribir en la memoria de pantalla en C (3)

Soy muy nuevo en C, es mi segundo lenguaje de programación de alto nivel después de Java. He bajado la mayoría de los conceptos básicos, pero por alguna razón no puedo escribir un solo carácter en la memoria de la pantalla.

Este programa se compila utilizando Turbo C para DOS en un Am486-DX4-100 que se ejecuta a 120 mhz. La tarjeta gráfica es un VLB Diamond Multimedia Stealth SE muy estándar que utiliza un chip Trio32.

Para un sistema operativo estoy ejecutando PC-DOS 2000 con una página de códigos ISO cargada. Estoy ejecutando en modo de texto de columna de estilo 80 MDA / CGA / EGA / VGA estándar con color.

Aquí está el programa como lo tengo escrito:

#include <stdio.h> int main(void) { unsigned short int *Video = (unsigned short int *)0xB8000; *Video = 0x0402; getchar(); return 0; }

Como dije, soy muy nuevo en C, así que me disculpo si mi error parece obvio, no pude encontrar una fuente sólida sobre cómo hacer esto que pudiera entender.

Que yo sepa, en el modo real en la plataforma x86, la memoria de pantalla para el modo de texto comienza en 0xB8000. Cada carácter se almacena en dos bytes, uno para el carácter y otro para el fondo / primer plano. La idea es escribir el valor 0x0402 (que debería ser una cara sonriente roja) en 0xB8000. Esto debería ponerlo en la parte superior izquierda de la pantalla.

He tenido en cuenta la posibilidad de que la pantalla pueda desplazarse y, por lo tanto, eliminar inmediatamente mi personaje al ejecutarlo de dos maneras. Para resolver este problema, he intentado:

  • Escribe repetidamente este valor usando un bucle
  • Escríbelo un poco más abajo.

Puedo leer e imprimir el valor que escribí en la memoria, por lo que obviamente todavía está en algún lugar de la memoria, pero por alguna razón no aparece nada en la pantalla. Obviamente estoy haciendo algo mal, pero no sé cuál podría ser el problema. Si necesita algún otro detalle, por favor pregunte. Gracias por cualquier posible ayuda que pueda dar.


Como @stacker señaló, en el entorno de 16 bits debe asignar el puntero con cuidado. AFAIK necesitas poner la palabra clave FAR (Dios mío, qué nostalgia).

También asegúrese de no compilar en el llamado modelo de memoria "Enorme". Es incompatible con el direccionamiento remoto, porque cada puntero de 32 bits se "normaliza" automáticamente a 20 bits. Intenta seleccionar el modelo de memoria "Grande".


En el modo real, para abordar el primer 1MiB completo de memoria, se utiliza un mecanismo llamado segmento de 20 bits: direccionamiento de desplazamiento . 0xb8000 es una dirección de memoria física. Debe usar algo llamado puntero far que le permita abordar la memoria con la segmentación en modo real. Los diferentes tipos de punteros se describen en esta Respuesta de

0xb8000 puede representarse como un segmento de 0xb800 y un desplazamiento de 0x0000. El cálculo para obtener la dirección física es el segmento * 16 + offset. 0xb800 * 16 + 0x0000 = 0xb8000. Teniendo esto en cuenta, puede incluir dos.h y usar la macro MK_FP C para inicializar un puntero far a un segmento y una compensación de esa dirección.

De la documentation se define MK_FP como:

MK_FP () Hacer un puntero lejano

#include <dos.h> void far *MK_FP(seg,off); unsigned seg; Segment unsigned off; Offset

MK_FP () es una macro que hace un puntero lejano desde su segmento componente ''seg'' y desplaza las partes ''off''.

Devoluciones: Un puntero lejano.

Tu código podría escribirse así:

#include <stdio.h> #include <dos.h> int main(void) { unsigned short int far *Video = (unsigned short int far *)MK_FP(0xB800,0x0000); *Video = 0x0402; getchar(); return 0; }


La dirección del segmento de memoria depende del modo de video utilizado:

0xA0000 for EGA/VGA graphics modes (64 KB) 0xB0000 for monochrome text mode (32 KB) 0xB8000 for color text mode and CGA-compatible graphics modes (32 KB)

Para acceder directamente a vram, necesita un puntero de 32 bits para mantener el segmento y la dirección de compensación; de lo contrario, podría estropear su montón. Esto generalmente conduce a un comportamiento indefinido.

char far *Video = (char far *)0xb8000000;

Ver también: ¿Qué son los punteros cercanos, lejanos y grandes?