When looking at my old A86/TASM sources from DOS/Win3x/9x times I've found some examples that might be useful for some DOS die hard fans especially when looking at some recent topics on this forum it occurred to me that a lot of DOS knowledge has been forgotten. Programming DesqView is one such example of once great and real Windows competitor before 3.0 and especially 3.1 times. You could even run Win30 under DesqView
Below is minimal working example demonstrating how to make your DOS DesqView aware application and the source has been converted from TASM to FASM.
To test it run it under DesqView in multiple DOS windows and watch how video buffer segment is changing per window.
Have fun!
format mz ;DesqView does not provide own executable file format
entry cseg:_start ;instead plain MZ EXEs are being used
;additional features can be controlled with PIF or DVP files
macro DOS_DISPLAY msg {
mov ah,9
mov dx,msg
int 21h
}
;=========================================================================================
segment dseg
dv_ver dw 0
video_seg dw 0
conv_buf db '0000$'
msg_crlf db 13,10,'$'
msg_nodsq db 'This program requires DesqView to be run.',13,10,'$'
msg_found db 'DesqView has been found ',13,10,'$'
msg_vbuf db 'DesqView video buffer segment: $'
msg_dsq db 'Hello World from DesqView critical section!',13,10,'$'
;=========================================================================================
segment cseg
IN_DV db 0 ;This is flag should be set if in DesqView according to
;DsqV documentation so we follow the standard
;IN_DV should in CS segment
;-----------------------------------------------------------------------------------------
find_deqview:
mov ax,2b01h
mov cx,4445h ;mov cx,'DE'
mov dx,5351h ;mov dx,'SQ'
int 21h
cmp al,0ffh
jnz .found_dsq
xor ax,ax
stc
ret
.found_dsq:
mov [cs:IN_DV],1
mov ax,bx ;store version number in AX
clc
ret
;-----------------------------------------------------------------------------------------
find_vbuf:
cmp [cs:IN_DV],1
je .find_vbuf
stc
ret
.find_vbuf:
push es
mov ah,0feh
int 10h
mov ax,es
pop es
clc
ret
;-----------------------------------------------------------------------------------------
dqv_begin_critical:
cmp [cs:IN_DV],1 ;Quarterdeck is using this method for testing IN_DV flag
je .bcrit
stc
ret
.bcrit:
mov ax,101bh
int 15h
ret
;-----------------------------------------------------------------------------------------
dqv_end_critical:
cmp [cs:IN_DV],1
je .ecrit
stc
ret
.ecrit:
mov ax,101ch
int 15h
ret
;-----------------------------------------------------------------------------------------
dqv_pause:
cmp [cs:IN_DV],1
je .pause
stc
ret
.pause:
mov ax,1000h
int 15h
ret
;-----------------------------------------------------------------------------------------
; *** ENTRY POINT ***
;-----------------------------------------------------------------------------------------
_start:
push dseg
pop ds
push dseg
pop es
;find if DesqView is running first
call find_deqview
jc _no_dsq_exit ;no DesqView
test ah,ah ;no DesqView base on major.minor version number
jz _exit
mov word [dv_ver],ax ;store DesqView version for further reference
DOS_DISPLAY msg_found
call find_vbuf
jc @f ;failed to find video buffer
mov word [video_seg],ax
mov di,conv_buf
mov dx,ax
call hexconvw
DOS_DISPLAY msg_vbuf
DOS_DISPLAY conv_buf
DOS_DISPLAY msg_crlf
@@:
;test critical section handling
call dqv_begin_critical
DOS_DISPLAY msg_dsq
call dqv_end_critical
call dqv_pause
;delay loop for dqv_pause
cld
xor ecx,ecx
.loop:
nop
loopd .loop
_exit:
mov ah,4ch
int 21h
_no_dsq_exit:
DOS_DISPLAY msg_nodsq
jmp _exit
;=========================================================================================
hexconvw: ;DX=word to convert DI=offset to 4 byte buffer
mov ch,4
cld
.rloop:
mov cl,4
rol dx,cl
mov al,dl
and al,0fh
add al,30h
cmp al,3ah
jl @f
add al,7h
@@:
stosb
dec ch
jnz .rloop
ret