Enable MS-DOS graphics in Windows 7 32-bit (ZULIA.COM)

Programming, for all ages and all languages.
Post Reply
User avatar
~
Member
Member
Posts: 1226
Joined: Tue Mar 06, 2007 11:17 am
Libera.chat IRC: ArcheFire

Enable MS-DOS graphics in Windows 7 32-bit (ZULIA.COM)

Post by ~ »

How to call old INT 10h from replaced vector (ZULIA.COM)

How can I call the previous BIOS interrupt from an interrupt I've installed?

It crashes when executing:

Code: Select all

jmp far dword[old10h]

pointer from the old ISR, when executing INT 10h.



Here is my code. What I want to do is create a program that installs an INT 10h vector that first calls the original video BIOS services and then sets up the VGA registers manually for standard VGA modes 3h, 4h, 12h, 13h, etc. This enables displaying CGA/EGA/VGA graphics under Windows 7 32-bit if you disable video driver/open Alt+Enter fullscreen console/reenable video driver (I've planned to enable this for being able to make use of old graphical DOS programs for which I don't have source under Windows 7 by calling the modified INT 10h regularly every time console graphics become unloaded):

New ISR:

Code: Select all

;nasm 710patch.asm -o 710patch.bin

;Copy it to 7FFF:0000
;or other free 64K segment


org 0
bits 16


old10h:
offset10h  dw 4
segment10h dw 0x7FFF



_int10h:

;Save return address:
;;
 pop word[_FLAGS]
 pop word[_IP]
 pop word[_CS]



;Build an IRET return address/FLAGS:
;;
 pushf
 cli
 push cs
 push word ret0
 jmp far dword[old10h]  ;This pointer is set up in zulia.asm


;Control to see if it crashes
;in the very previous line:
;;
 ret0:
 jmp $




;Build final return address:
;;
 push word[_CS]
 push word[_IP]
 push word[_FLAGS]
iret












_FLAGS dw 0
_IP dw 0
_CS dw 0


_EAX dd 0
_EBX dd 0
_ECX dd 0
_EDX dd 0
_ESI dd 0
_EDI dd 0
_EBP dd 0



align 16



COM program to install the ISR:

Code: Select all

;nasm zulia.asm -o zulia.com

org 100h
bits 16

;Write text mode ZULIA screen
;;



;If patch is already installed, skip:
;;
 ;If DWORD at 0000h:10h*4 is == 0x7FFF0004,
 ;we have already installed it.
 ;
 ;Just display the splash.



;Copy interrupt vector.
;It's in format:
;
;Word 0 -- Offset
;Word 1 -- Segment
;;
 mov esi,10h*4
 xor eax,eax

 push ds
 pop es

 push ds
 push word 0
 pop ds          ;DS:SI base == 0 (real mode IVT)

 mov edi,[esi]      ;Get old IDT vector
 mov [es:old10h],edi   ;Save in old variable
 mov edi,0x7FFF0004 ;Set new vector
 mov dword[esi],edi ;Place new pointer

 pop ds



;Copy patch to destination segment:
;7FFF:0000:
;;
 push es

 mov esi,patch10h     ;DS:ESI  == our embedded ISR

 push word 0x7FFF     ;ES:EDI - Segment 7FFF:0000
 pop es
 xor edi,edi

 mov ecx,patch10h_SZ

 ;Align REP instruction to DWORD/WIDEWORD
 ;to make it faster:
 ;;
  align 4
  rep movsb



 pop es




mov ax,4C00h
int 21h




;The order of labels according
;of structure:
;;

align 4
old10h:
patch10h:
incbin "710patch.bin"
patch10h_END:
patch10h_SZ equ (patch10h_END-patch10h)/10*10

Last edited by ~ on Sun Oct 27, 2019 5:54 pm, edited 1 time in total.
YouTube:
http://youtube.com/@AltComp126

My x86 emulator/kernel project and software tools/documentation:
http://master.dl.sourceforge.net/projec ... 7z?viasf=1
User avatar
iansjack
Member
Member
Posts: 4685
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: How to call old INT 10h from replaced vector (ZULIA.COM)

Post by iansjack »

This is really not OS Development. It should be in General Programming.
nullplan
Member
Member
Posts: 1766
Joined: Wed Aug 30, 2017 8:24 am

Re: How to call old INT 10h from replaced vector (ZULIA.COM)

Post by nullplan »

So you're trying to install an ISR into Windows 7's DOS emulation? I'm guessing that would work better if you went the standard route. Something like:

Code: Select all

org 100h
bits 16

old10h: jmp install
align 4
new10h:
; how about we just save the return values on stack?
pushf
call far [cs:old10h]

; if you get here, be happy
ret: sti
hlt
jmp ret

iret

install:
; OK, so CS must be initialized. What about DS?
mov ax, cs
mov ds, ax
mov ax, 2510h
int 21h
mov [old10h], bx
mov [old10h + 2], es
mov dx, new10h
int 21h

mov dx, (install + 15)/16
mov ax, 3100h
int 21h
That is the way most TSRs work, and what the Windows 7 DOS emulation is likely expecting: The program exits with the TSR function, instead of the normal exit function. The vector is read and written using DOS functions.

It is entirely possible that the DOS emulation in Windows 7 thinks all memory is free after the exit from your COM. Also, a few points of order:

1. On entry to the ISR, you can expect CS to be set up, but DS, ES, and SS are not (necessarily) set to the same value. Therefore, you must always use a CS override, or else switch DS to being equal to CS.
2. You don't have to push a return address yourself. A far call instruction does exist.
Carpe diem!
User avatar
~
Member
Member
Posts: 1226
Joined: Tue Mar 06, 2007 11:17 am
Libera.chat IRC: ArcheFire

Re: How to call old INT 10h from replaced vector (ZULIA.COM)

Post by ~ »

It seems that it should be possible to remap the old INT 10h pointer to a free interrupt slot.

But it's probably funnier/more educative to jump and IRETing from a manually built far call interrupt address.
YouTube:
http://youtube.com/@AltComp126

My x86 emulator/kernel project and software tools/documentation:
http://master.dl.sourceforge.net/projec ... 7z?viasf=1
User avatar
~
Member
Member
Posts: 1226
Joined: Tue Mar 06, 2007 11:17 am
Libera.chat IRC: ArcheFire

Re: How to call old INT 10h from replaced vector (ZULIA.COM)

Post by ~ »

I have managed to create a DOS resident TSR program that installs an INT 10h wrapper that basically calls original INT 10h and then sets VGA registers manually, as that's the method that allows displaying graphics under Windows 7 32-bit.

Just run ZULIA.COM and then the program you want to display from the same console.

It makes possible to run VGA programs for which there's no source. Fixing INT 10h to the requirements of Windows 7 is equivalent to fix those programs from source (but I can't make all of the programs work with this early-released patch attempt).

Supported modes so far are:
3h
4h
12h
13h

I'm trying to figure the method used by ZSNES that allows properly displaying VESA modes under Windows 7 too, so I can add them (or try to figure yourself and tell me so I add them).

VESA will be extremely useful for things like displaying demo splashes, newer DOS games and things like the OS book CDs from Ben Lunt.

With this I'm now able to play a number of old games and graphical DOS programs under Windows 7.

Code: Select all

List of programs that work with ZULIA.COM
CGA/EGA/VGA patch.

Z26 (Atari emulator)
Denthor of Asphixya tutorials
Graphics programs from programmersheaven, Planet Source Code, etc.
Window manager demo from Alexei Frounze
Nesticle with the latest DOS32a



-8088 games-
ALF
Bouncing Babies
MS Pacman
Rush N' Attack





-What doesn't work-

VESA modes (find out how to handle with ZSNES)
BGI drivers (EGAVGA.BGI)

See the attached ZIP and run ZULIA.COM.

Don't forget to disable graphics driver/open console with Alt+Enter/reenable graphics driver in Windows 7 32-bit.
Attachments
ZULIA-2019-10-26.zip
(59.85 KiB) Downloaded 244 times
ZULIA-2019-10-14.zip
(62.02 KiB) Downloaded 214 times
ZULIA-2019-10-13.zip
(58.38 KiB) Downloaded 213 times
YouTube:
http://youtube.com/@AltComp126

My x86 emulator/kernel project and software tools/documentation:
http://master.dl.sourceforge.net/projec ... 7z?viasf=1
User avatar
~
Member
Member
Posts: 1226
Joined: Tue Mar 06, 2007 11:17 am
Libera.chat IRC: ArcheFire

Re: Enable MS-DOS graphics in Windows 7 32-bit (ZULIA.COM)

Post by ~ »

I've been doing more tests for VESA and it doesn't seem that Windows 7 enables the graphics mode, it only enters fullscreen mode when calling INT 10H AH=4Fh services, even with the screen driver disabled.

But this is in a ProBook 6470b.

Maybe older machines with this OS could behave better, as I seem to remember with the sole act of disabling the driver.

The problem with the 6470b is that programs and even the Windows 7 VGA BIOS don't seem to program all due registers, so we are forced to reprogram them after calling the old chained INT 10H vector.
Attachments
detect.zip
(9.78 KiB) Downloaded 216 times
YouTube:
http://youtube.com/@AltComp126

My x86 emulator/kernel project and software tools/documentation:
http://master.dl.sourceforge.net/projec ... 7z?viasf=1
User avatar
~
Member
Member
Posts: 1226
Joined: Tue Mar 06, 2007 11:17 am
Libera.chat IRC: ArcheFire

Re: Enable MS-DOS graphics in Windows 7 32-bit (ZULIA.COM)

Post by ~ »

Windows 7 seems to not have any standard mode when opening a console window.

So we need to set mode 3h explicitly (we cannot assume absolutely anything in Windows, specially 7, about the initial state of something).

Try to remove the call to INT 10H AX=03h from the attached program (that shows a SCANDISK.EXE text mode screen snapshot) and you will see that Windows 7 doesn't work (the consoles aren't working in mode 03h).

We would need to call INT 10H AH=0Fh (AL=current video mode) to see which mode number Windows works in.
Attachments
scandisk_screen.zip
(58.35 KiB) Downloaded 203 times
YouTube:
http://youtube.com/@AltComp126

My x86 emulator/kernel project and software tools/documentation:
http://master.dl.sourceforge.net/projec ... 7z?viasf=1
Post Reply