Cannot write to screen memory in C

In real mode to address the first full 1MiB of memory a mechanism called 20-bit segment:offset addressing is used. 0xb8000 is a physical memory address. You need to use something called a far pointer that allows you to address memory with real mode segmentation. The different types of pointers are described in this Stackoverflow Answer

0xb8000 can be represented as a segment of 0xb800 and an offset of 0x0000. The calculation to get physical address is segment*16+offset. 0xb800*16+0x0000=0xb8000. With this in mind you can include dos.h and use the MK_FP C macro to initialize a far pointer to such an address given segment and offset.

From the documentation MK_FP is defined as:

MK_FP() Make a Far Pointer

#include   <dos.h>

void       far *MK_FP(seg,off);
unsigned   seg;                         Segment
unsigned   off;                         Offset

MK_FP() is a macro that makes a far pointer from its component segment 'seg' and offset 'off' parts.

Returns: A far pointer.

Your code could be written like this:

#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;
}

As @stacker pointed-out, in the 16-bit environment you need to assign the pointer carefully. AFAIK you need to put FAR keyword (my gosh, what a nostalgia).

Also make sure you don't compile in so-called "Huge" memory model. It's incompatible with far addressing, because every 32-bit pointer is automatically "normalized" to 20 bits. Try selecting "Large" memory model.


The memory segment adress depends on the video mode used:

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)

To directly access vram you need a 32 bit-pointer to hold segement and offset address otherwise you would mess up your heap. This usually leads to undefined behaviour.

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

See also: What are near, far and huge pointers?