//------------------------------------------------------------------- // bluetext.cpp // // This short demo program shows the essential steps needed for // executing 'Real Mode' code in Virtual-8086 Mode under Linux, // assuming i/o-sensitive instructions will not be encountered. // // This demo is designed to be run from a text-mode console (no // effect will be visible if executed from a graphics console). // // NOTE: In order to allow writing to the system's video memory // without requiring special privileges, this program relies on // the services provided by our 'dos.c' device-driver module. // // programmer: ALLAN CRUSE // written on: 26 MAY 2005 //------------------------------------------------------------------- #include // for printf(), perror() #include // for open() #include // for exit() #include // for mmap() #include // for vm86() #include // for 'asmlinkage' attribute #define PROT ( PROT_READ | PROT_WRITE ) #define FLAG ( MAP_FIXED | MAP_SHARED ) asmlinkage void blue( void ); // prevents C++ name-mangling asm(" .code16 "); asm(" .align 16 "); asm("blue: "); asm(" movw $0xB800, %ax "); asm(" movw %ax, %es "); asm(" xorw %di, %di "); asm(" movb $0x17, %al "); asm(" movw $0x4000, %cx "); asm("nxpel: "); asm(" movb %al, %es:1(%di) "); asm(" addw $2, %di "); asm(" loop nxpel "); asm(" hlt "); asm(" .code32 "); int main( void ) { int fd; // setup a memory-mapping for accessing video display memory void *vram = (void*)0x000B8000; // address of 32KB window if ( ( fd = open( "/dev/dos", O_RDWR ) ) < 0 ) { perror( "/dev/dos" ); exit(1); } if ( mmap( vram, 0x8000, PROT, FLAG, fd, (int)vram ) == MAP_FAILED ) { perror( "mmap /dev/dos" ); exit(1); } // setup a memory-mapping for accessing our vm86 code and stack void *prog = (void*)0x00010000; // address of 64KB window if ( ( fd = open( "/dev/zero", O_RDWR ) ) < 0 ) { perror( "/dev/zero" ); exit(1); } if ( mmap( prog, 0x10000, PROT, FLAG, fd, 0 ) == MAP_FAILED ) { perror( "mmap /dev/zero" ); exit(1); } // now 'load' our 16-bit program-code into this memory region char *dst = (char*)prog; char *src = (char*)blue; for (int i = 0; i < 0x10000; i++) if ( ( dst[i] = src[i] ) == (char)0xF4 ) break; // compute starting addresses for the real-mode code and stack int initial_CS = ((int)prog) >> 4; int initial_IP = 0; int initial_SS = ((int)prog) >> 4; int initial_SP = 0; // initialize data-structure for entering Virtual-8086 Mode struct vm86plus_struct vm = {0}; vm.regs.eip = initial_IP; vm.regs.cs = initial_CS; vm.regs.esp = initial_SP; vm.regs.ss = initial_SS; vm.regs.eflags = (1<<9); // IF=1, IOPL=0 vm.cpu_type = CPU_586; // execute in Virtual-8086 Mode (until 'hlt' is encounterd) vm86( VM86_ENTER, &vm ); printf( "\nReturned successfully from Virtual-8086 Mode\n\n" ); }