home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DOS/V Power Report 1998 January (DVD)
/
VPR980100.ISO
/
OLS
/
DOS
/
MILD7130
/
MILD7130.LZH
/
SOURCE.LZH
/
MILD7.ASM
< prev
Wrap
Assembly Source File
|
1994-04-22
|
27KB
|
1,129 lines
; MILD7 - Video7 Emulator
; Copyright (c) 1993, 1994, Kyosuke Tokoro
; All rights reserved
VER equ '1.30'
;================================================================
; Ver Note
;----------------------------------------------------------------
; 0.99 Pre-released test program
; 1.00 Added Video7 functions (AH=6Fh)
; 1.01 Added /unload switch for remove resident from memory
; No check BX when entering function 6F00h
; 1.02 Optimized for size
; Purge null functions (AX=6F05h, 6F07h)
; Changed some messages
; Added more stack area
; Change algorithm of checking installation
; 1.10 Can install as a device driver
; 1.20 Added mode chage feature
; 1.21 Added help (/?) option
; Change algorithm of main driver interrupt routine
; 1.22 Check DBCS vector befor video mode setting
; Fix bug in error handling during video mode setting
; 1.23 Fix bug in function 1Bh of video BIOS
; 1.24 No clear the screen if the high bit of video mode is set
; 1.25 Added ON/OFF swich
; Support video modes 41h and 5Bh
; 1.30 Automatic disable when starts MS-Windows
; Fix bug that can't recognize vmode when loading high
;================================================================
.286
include macros.inc
;======================
; VGA Port Definitions
;======================
VGAMiscW equ 3C2h ;(Write) Miscellaneous Output Register
BWStat1 equ 3BAh ;(Read) Status Register 0 (in monochrome mode)
VGAStat1 equ 3DAh ;(Read) Status Register 0 (in color emulation)
VGAMiscR equ 3CCh ;(Read) Miscellaneous Output Register
CRTC equ 3D4h ;(R/W) Display Controller
;-----------------------
; CRTC Initialize Value
; for 80x60 Text Mode
;-----------------------
VertTatal equ 523 ;Vertical Total
StrtVertBlank equ 487 ;Start Vertical Blank
VertRetrStrt equ 490 ;Vertical Retrace Start
VertRetrEnd equ 492 ;Vertical Retrace End
EndVertBlank equ 516 ;End Vertical Blank
;===================
; BIOS Data Segment
;===================
bios segment at 0'BIOS'
org 449h
VideoMode db ? ;Video current mode
VideoCols label byte
columns dw ? ;Video columns on screen
RegenSize dw ? ;Video page (regen buffer) size in bytes
org 462h
VideoPage db ? ;Video current page number
org 484h
VideoRows db ? ;Video rows on screen minus one
VideoScan label byte
CharHeight dw ? ;Video character height in scan-lines
db ?
VGASw db ? ;Video VGA switches
ModeOption db ? ;Video MCGA/VGA mode-set option control
bios ends
;===========================
; Program Code/Data Segment
;===========================
code segment word public'CODE'
top label
;======================
; Device Driver Header
;======================
dd -1 ;Link to next driver (-1 for none)
dw 8000h ;Device attributes
dw strategy ;Strategy-routine offset
dhCmd dw command ;Interrupt-routine offset
db 'MILD7VGA' ;Logical-device name
sign db VER ;Version signature
;==========================
; Request Packet Structure
;==========================
;*** Request Packet Header ***
RqHeader struc
db ? ;Length of record, in bytes
db ? ;(not for the charecter device)
rhFunc db ? ;Function number
rhStat dw ? ;Status
db 8 dup(?) ;(reserved)
RqHeader ends
;*** Intialize Request Packet ***
InitReq struc
RqHeader<>
db ? ;(not for the charecter device)
irEnd dd ? ;INPUT: end available driver memory
;OUTPUT: end resident code
irParam dd ? ;INPUT: addr CONFIG.SYS device= line
;OUTPUT: (not for the charecter device)
db ? ;(not for the charecter device)
irMsgFlag dw ? ;OUTPUT: error-message flag
InitReq ends
;====================
; Resident Work Area
;====================
;*** Instance Item ***
even
instance dd InstTop ;Address of instance data
dw InstSize ;Size of instance data
dd 0 ;End of array
;*** Startup Information ***
StartInfo db 3 ;Major version of info structure
db 0 ;Minor version of info structure
NextInfo dd ? ;Pointer to next startup info structure or 0000h:0000h
dd 0 ;Pointer to ASCIZ name of VxD file or 0000h:0000h
dd 0 ;virtual device reference (only used if above nonzero)
InstItem dd instance ;Pointer to instance data records
;***
irp i,<10h,2Fh>
_org&i dd ? ;Original int i vector
endm
psp dw 0 ;Segment address of PSP (valid only initialized as TSR)
request dd ?
InstTop label
ReqMode dw ? ;Required video mode
SubCmd db ? ;Subcommand for load rom character pattern
;------------------
; Status flag bits
;------------------
SBAVAIL equ 80h ;Statback is valid flag
ACTIVE equ 40h ;MILD7 BIOS active flag
EmuStat db ACTIVE
InstSize equ $-InstTop
StatBack db ACTIVE
;======================
; CRTC Bit Programming
;======================
; DX = CRTC port address
; AL = index
; CL = data
; CH = mask
; Return: AL = output value
assume cs:code
bitCRTC proc near
cli
out dx,al
inc dx
in al,dx
and al,ch
or al,cl
out dx,al
dec dx
ret
bitCRTC endp
;================
; Unprotect CRTC
;================
; DX = CRTC port address
; Return: AX = value for protect
unprotect proc near
push cx
mov ax,1111h ;AH = AL = 11h (Index to vertical retrace end)
mov cx,7000h+(VertRetrEnd and 0Fh)
call bitCRTC
pop cx
or al,80h ;Make value for protect CRTC
xchg al,ah ;
ret
unprotect endp
;========================
; CRTC 5 bit Porgramming
;========================
; DX = CRTC port address
; AL = index
; CL = data (bit 7-5 must be 0)
; Return: AL = AL + 1
; CL = CL - 1
CRTC5bit proc near
dec cl
CRTC5bit0 proc
mov ch,0E0h
push ax
call bitCRTC
pop ax
inc ax
ret
CRTC5bit0 endp
CRTC5bit endp
;========================
; Call Int 10h in Mode 3
;========================
; DS = bios
; AH = function code
assume ds:bios
org10h proc near
push word ptr VideoMode
mov VideoMode,3
int 10h
pop word ptr VideoMode
ret
org10h endp
;=========================
; Video BIOS Trap Handler
;=========================
;------------------
; Function 6F01h
; Get Monitor Info
;------------------
; AX = 6F01h
; Return: AH = status register information
; bit 0 = display enable
; 0 = display enabled
; 1 = vertical or horizontal retrace in progress
; bit 1 = 0 (reserved as light pen flip flop status)
; bit 2 = 0 (reserved as light pen switch activation status)
; bit 3 = vertical sync
; bit 4 = 0 (reserved as monitor resolution status)
; bit 5 = 0 (reserved as display type)
; bits6,7= 0 (reserved as diagnostic bits)
; Note: Bits 0-3 are the same as the VGA status register bit 0-3
assume ds:nothing
_6F01h: push dx
mov dx,VGAMiscR
in al,dx
mov dl,low BWStat1
testif al,1,z,_6F01h0
mov dl,low VGAStat1
_6F01h0:in al,dx
pop dx
and al,0Fh
mov ah,al
mov al,1 ;Restore caller's AL value
iret
;--------------------------------
; Function 6F04h
; Get Mode and Screen Resolution
;--------------------------------
; AX = 6F04h
; Return: AL = current video mode
; BX = horizontal columns
; CX = vertical columns
assume ds:bios
_6F04h: push ds
xor bx,bx
mov ds,bx
mov al,VideoMode
mov bx,columns
mov cl,VideoRows
xor ch,ch
inc cx
pop ds
iret
;--------------------
; Function 6F00h
; Installation Check
;--------------------
; AX = 6F00h
; Return: BX = 5637h ('V7')
assume ds:nothing
_6F00h: testif EmuStat,ACTIVE,z,DoOrg10h
mov bx,5637h
iret
;-----------------------
; Function 6Fh
; Video7 BIOS Emulation
;-----------------------
_6Fh: if_ al,b,1,_6F00h
je _6F01h
if_ al,b,4,DoOrg10h
je _6F04h
if_ al,e,5,_6F05h
if_ al,ne,3Fh,DoOrg10h
;----------------------
; Function 6F3Fh
; Get Resident Segment
;----------------------
; AX = 6F3Fh
; Return: AX = 3F6Fh
; ES = Resident segment address
_6F3Fh: movp es,cs
xchg al,ah
iret
;----------------
; Function 6F05h
; Set Video Mode
;----------------
; AX = 6F05h
; BL = mode
_6F05h: push ax
xor ah,ah ;Set video mode
mov al,bl ;
int 10h ;
pop ax
iret
;---------------------------------
; Function 1Bh
; Functionality/State Information
;---------------------------------
; AH = 1Bh
; BX = implementation type
; 0000h return funtionality/state information
; ES:DI -> 64-byte buffer for state information (see below)
; Return: AL = 1Bh if function supported
; ES:DI buffer filled with state information
; Format of state information:
; Offset Size Description
; 00h DWORD address of static funtionality table
; 04h BYTE video mode in effect
; 05h WORD number of columns
; 07h WORD length of regen buffer in bytes
; 09h WORD starting address of regen buffer
; 0Bh WORD cursor position for page 0
; 0Dh WORD cursor position for page 1
; 0Fh WORD cursor position for page 2
; 11h WORD cursor position for page 3
; 13h WORD cursor position for page 4
; 15h WORD cursor position for page 5
; 17h WORD cursor position for page 6
; 19h WORD cursor position for page 7
; 1Bh WORD cursor type
; 1Dh BYTE active display page
; 1Eh WORD CRTC port address
; 20h BYTE current setting of register (3?8)
; 21h BYTE current setting of register (3?9)
; 22h BYTE number of rows
; 23h WORD bytes/character
; 25h BYTE display combination code of active display
; 26h BYTE DCC of alternate display
; 27h WORD number of colors supported in current mode
; 29h BYTE number of pages supported in current mode
; 2Ah BYTE number of scan lines active
; (0,1,2,3) = (200,350,400,480)
; 2Bh BYTE primary character block
; 2Ch BYTE secondary character block
; 2Dh BYTE miscellaneous flags
; 2Eh 3 BYTEs reserved (00h)
; 31h BYTE video memory available
; 00h = 64K, 01h = 128K, 02h = 192K, 03h = 256K
; 32h BYTE save pointer state flags
; 33h 13 BYTEs reserved (00h)
assume ds:bios
_1Bh: if_ al,ne,ah,_1BhQ
jbxnz _1BhQ
mov al,VideoMode
and al,7Fh
mov byte ptr es:[di+4],al
mov word ptr es:[di+29h],303h
mov al,ah
_1BhQ: iret
;--------------------
; Int 10h Main Entry
;--------------------
assume ds:nothing
int10h proc far
jahz _00h
if_ ah,e,0Fh,_0Fh
if_ ah,e,6Fh,_6Fh
assume ds:bios
push ds
movp ds,bios
irp i,<41h,43h,5Bh>
if_ VideoMode,e,i,SetMode3
endm
DoOrg10h0:pop ds
_0Fh:
DoOrg10h:jmp _org10h
SetMode3:if_ ah,ne,11h,?1Bh
jmp _11h
?1Bh: cmp ah,1Bh
pushf
call org10h
pops <f,ds>
je _1Bh
iret
;----------------
; Function 00h
; Set Video Mode
;----------------
; AH = 00h
; AL = mode
; 41h 80x34 text mode (Diamond Speedstar 24X, WD90C)
; 43h 80x60 text mode (Video7, VEGA, Tatung)
; 5Bh 80x30 text mode (ATI VGA Wonder)
assume ds:nothing
_00h: push ax
and al,7Fh
mov ah,11h ; 8x14 font
if_ al,e,41h,_00h0 ;80x34 text
inc ah ; 8x 8 font
if_ al,e,43h,_00h0 ;80x60 text
mov ah,14h ; 8x16 font
if_ al,e,5Bh,_00h0 ;80x30 text
pop ax
jmp DoOrg10h
_00h0: mov SubCmd,ah
pop ReqMode
assume ds:bios
push ds
xor ax,ax
mov ds,ax
push word ptr VGASw
push bx
mov ax,1201h ;Select vertical resolution
mov bl,30h ; 350 scan lines
int 10h ;
pop bx
mov ax,ReqMode ;Set video mode
and al,80h ;
or al,3 ;
int 10h ;
pop word ptr VGASw
pop ds
assume ds:nothing
push dx
mov dx,VGAMiscW
mov al,11100011b
; |||||||+----- I/O Address Select = 3DXh for CGA Emulation
; ||||||+------ Enable RAM
; ||||++------- Selects 25.175 MHz clock for 640 Horz PELs
; |||+--------- Reserved = 0
; ||+---------- Page Bit for Odd/Even
; ++----------- 480 lines
out dx,al
mov dl,low CRTC
call unprotect
outcrtc macro index,value
mov ax,(low value)*100h+index
out dx,ax
endm
outcrtc 6,VertTatal
overflow= ((VertTatal shr 4)and 20h)or((high VertTatal)and 1)
OflMask = 0DEh
outcrtc 10h,VertRetrStrt
overflow= overflow or((VertRetrStrt shr 2)and 80h) \
or((VertRetrStrt shr 6)and 4)
OflMask = OflMask and 7Bh
outcrtc 15h,StrtVertBlank
overflow= overflow or((StrtVertBlank shr 5)and 8)
OflMask = OflMask and 0F7h
outcrtc 16h,EndVertBlank
push cx
mov al,7
mov cx,(OflMask shl 8)+overflow
call bitCRTC
mov al,9
mov cx,0DF00h+((StrtVertBlank shr 4)and 20h)
call bitCRTC
pops <cx,dx>
assume ds:bios
push ds
xor ax,ax
mov ds,ax
mov al,byte ptr ReqMode
mov VideoMode,al
pop ds
assume ds:nothing
push bx
mov ah,11h ;Load ROM character
mov al,SubCmd
xor bl,bl ;to block 0
int 10h ;
pop bx
mov ax,ReqMode ;Restore caller's AX value
iret
;-----------------------------------------
; Function 11h
; Text-Mode Character Generator Functions
;-----------------------------------------
; AH = 11h
; The following functions will cause a mode set, completely resetting
; the video environment, but without clearing the video buffer
; AL = 00h, 10h: load user-specified patterns
; ES:BP -> user table
; CX = count of patterns to store
; DX = character offset into map 2 block
; BL = block to load in map 2
; BH = number of bytes per character pattern
; AL = 01h, 11h: load ROM monochrome patterns (8 by 14)
; BL = block to load
; AL = 02h, 12h: load ROM 8 by 8 double-dot patterns
; BL = block to load
; AL = 04h, 14h: load ROM 8x16 character set
; BL = block to load
; Notes: The routines called with AL=1xh are designed to be called only
; immediately after a mode set and are similar to the routines called
; with AL=0xh, except that:
; Page 0 must be active.
; Bytes/character is recalculated.
; Max character rows is recalculated.
; CRT buffer length is recalculated.
; CRTC registers are reprogrammed as follows:
; R09 = bytes/char-1 ; max scan line
; R0A = bytes/char-2 ; cursor start
; R0B = 0 ; cursor end
; R12 = ((rows+1)*(bytes/char))-1 ; vertical display end
; R14 = bytes/char ; underline loc
assume ds:bios
_11h: if_ al,nb,10h,_11h0
xDoOrg10h0:jmp DoOrg10h0
_11h0: if_ al,e,13h,xDoOrg10h0
if_ al,a,14h,xDoOrg10h0
; Do load font
call org10h
; Unprotect CRTC
pushs <ax,cx,dx>
mov dx,CRTC
call unprotect
push ax ;Save AX value for protect CRTC
; Recalculate max character rows
; but doesn't save
mov ax,480
div byte ptr CharHeight
push ax ;Save for after use
; Reprogramme CRTC register 12
; (vertical display end)
mov al,ah ;AX = 480 modulo [CharHeight]
cbw ;
neg ax
add ax,480-1
mov cl,ah
mov ah,al
mov al,12h
out dx,ax ;+--CH--+ +--CL--+
; FEDCBA98
shl cl,1 ; EDCBA98.
mov ch,cl ;EDCBA98. EDCBA98.
and cx,402h ;.....9.. ......8.
shl ch,4 ;.9...... ......8.
or cl,ch ; .9....8.
mov ch,0BDh ;x.xxxx.x
mov al,7
call bitCRTC
; Recalculate CRT buffer length
pop ax
push ax
mul VideoCols
shl ax,1
add ax,0FFh
xor al,al
mov RegenSize,ax
; Save max character rows
pop ax
dec ax
mov VideoRows,al
; Protect CRTC
pop ax
out dx,ax
pops <dx,cx,ax,ds>
iret
int10h endp
;=================
; Int 2Fh Handler
;=================
assume ds:nothing
int2Fh proc far
if_ ax,e,1605h,InitDOSX
if_ ax,e,1606h,ExitWin
if_ ax,e,4B05h,IdInst
DoOrg2Fh:jmp _org2Fh
;-----------------------------------------------
; Function 1606h
; MS Windows Enhanced Mode Begin Exit Broadcast
;-----------------------------------------------
; AX = 1606h
ExitWin:testif EmuStat,SBAVAIL,z,DoOrg2Fh
push ax
mov al,StatBack
mov EmuStat,al
pop ax
jmp DoOrg2Fh
;-----------------------------------------------
; Function 1605h / 4B05h
; MS Windows Enh Mode Init Broadcast
; DOS 5+ Task Switcher - Identify Instance Data
;-----------------------------------------------
; AX = 1605h (Task Switcher)
; 4B05h (Windows)
; ES:BX = 0000h:0000h
; DS:SI = 0000h:0000h (Windows only)
; CX:DX -> task switcher entry point (Task Switcher only)
; CX = 0000h (Windows only)
; DX = flags
; bit 0 = 0 if Windows enhanced-mode initialization
; bit 0 = 1 if Microsoft 286 DOS extender initialization
; bits 1-15 reserved
; DI = version number (Windows only)
; Return: CX (Windows only)
; = 0000h if okay for Windows to load
; = FFFFh (other registers unchanged) if Windows in standard mode
; <> 0 if Windows should not load
; ES:BX -> startup info structure
; DS:SI -> virtual86 mode enable/disable callback (Windows only)
; or 0000h:0000h
InitDOSX:
IdInst: pushf ;Simulate 'int' operation
call _org2Fh ;
if_ ax,e,4B05h,LinkInst
jcxnz _iret
push ax
mov al,EmuStat
mov StatBack,al
and al,not ACTIVE
or al,SBAVAIL
mov EmuStat,al
pop ax
LinkInst:movd NextInfo,es,bx
mov bx,offset StartInfo ;ES:BX -> startup information structure
movp es,cs ;
_iret: iret
int2Fh endp
TSRSize equ $-top ;Resident size (installed as a TSR)
;==================
; Device Driver
; Strategy Routine
;==================
strategy proc far
movd request,es,bx
ret
strategy endp
;===================
; Device Driver
; Interrupt Routine
;===================
_command proc far
pushs <ds,bx>
lds bx,request
CmdFail:mov [bx].rhStat,810Ch ;General failure
CmdQ: pops <bx,ds>
ret
_command endp
DrvEnd label far
command proc far
pushs <ds,bx>
lds bx,request
if_ [bx].rhFunc,ne,0,CmdFail
call hello
call GetVect
call install
mov word ptr dhCmd,offset _command
movd [bx].irEnd,cs,<offset DrvEnd>
mov [bx].rhStat,100h ;Done
jmp CmdQ
command endp
;=================
; Message Strings
;=================
MsgHello db 13,10,'More Information Lines on your Display - Version '
db VER,' -',13,10,'Copyright (c) 1993, 1994, Kyosuke Tokoro. '
db 'All rights reserved.',13,10,10,'$'
MsgHelp db 'Usage:',9,' MILD7',9,'/UNLOAD',9,9,'Remove from memory.',13,10
db 10,9,' MILD7',9,'screen_mode',9,'Change screen mode.',13,10
db 9,9,9,9,'80x25, 80x30, 80x34, 80x43, 80x50 or 80x60',13,10,10
db 9,' MILD7',9,'OFF',9,9,'Disable Video7 BIOS emulation.',13,10
db 10,9,' MILD7',9,'ON',9,9,'Enable Video7 BIOS emulation.',13,10
db '$'
MsgBadVideo db 'Warnning: Unknown parameter specified is ignored.',13,10,10
db '$'
MsgNoUSMode db '注意: MILD7の画面モード設定機能はDBCS環境では利用できません.'
db 13,10,10,'$'
MsgInvSw db 'Invalid switch - /'
MsgInvSw0 db ?,'.',13,10,'$'
MsgAlready db 'Error:',9,'Video7 BIOS is in this system. '
db 'No MILD7 emulation is not required.',13,10
db 9,'Or a old version of MILD7 is already stayed in memory.'
db 13,10,'$'
MsgNotInst db 'Error:',9,'Cannot unload. MILD7 is not installed.',13,10
db 9,'Or resident MILD7 is a old version.',13,10,'$'
MsgBadVect db 'Error: Int 10h vector is traped by another progrem. '
db 'Cannot unload.',13,10,'$'
MsgUnload db 'Successfuly unloaded.',13,10,'$'
MsgNoTSR db 'Error: Cannot unload resident which was installed as a device'
db ' driver.',13,10,'$'
MsgInst db 'Successfuly installed.',13,10,'$'
MsgBadVer db 'Error: Resident MILD7 is a different version.',13,10,'$'
MsgStat db ' Video7 emulation: '
MsgEmu db 'ON ',13,10
db 'Video current mode: '
MsgMode db '00h Page: '
MsgPage db '00h',13,10
db ' Columns x Rows: '
MsgCols db ' 00 x'
MsgRows db ' 00 characters',13,10
db ' Character height: '
MsgScan db ' 0 scan lines / a character',13,10,'$'
;=====================
; Transient Work Area
;=====================
even
fcb dw 6Ch+1 ;Normaly 5Ch+1
resident dw 0 ;Segment address of resident code
;========================
; Video Mode Table
; for _SetMode Procedure
;========================
ModeTable dw 2 ;80x25
dw 1400h ;80x30
dw 1201h ;80x43
dw 1202h ;80x50
dw 0 ;80x60
; ||++---- Required scan lines: 0= 480; 1= 350; 2= 400
;========== ++------ Font to load: 0= default; 12h= 8x8; 14= 8x16
; Greeting
;==========
assume ds:code
hello proc near
pushs <ax,dx>
mov dx,offset MsgHello
call puts
pops <dx,ax>
HelloQ: ret
hello endp
;======================
; Get Interrupt Vector
;======================
assume ds:nothing
GetVect proc near
pushs <es,ax,bx>
irp i,<10h,2Fh>
mov ax,35&i ;Get int i vector
int 21h ;
movd _org&i,es,bx
endm
pops <bx,ax,es>
ret
GetVect endp
;======================
; Get Resident Address
;======================
GetResident proc near
push es
mov ax,6F3Fh
int 10h
if_ ax,ne,3F6Fh,GRQuit
assume es:code
mov dx,offset MsgBadVer
mov si,offset sign
mov di,si
cld
rept 2
cmps word ptr cs:sign,word ptr sign
jne xxPutRC1
endm
mov cs:resident,es
GRQuit: pop es
ret
xxPutRC1:jmp PutRC1
GetResident endp
;=========
; Install
;=========
assume ds:code,es:nothing
install proc near
pushs <ax,dx,ds>
movp ds,cs
irp i,<10h,2Fh>
mov ax,25&i
mov dx,offset int&i
int 21h ;Set interrupt vector
endm
pops <ds,dx,ax>
ret
install endp
;================
; Enable/Disable
;================
; DS = segment address of program segment prefix
; CX = resident code segment
; Return: CF if no valid paramter found
assume ds:nothing,es:code ;ES = resident code segment
OnOff proc near
push es
mov es,cx
mov bx,cs:fcb
inc bx
mov ax,[bx]
if_ ax,e,'FF',off
if_ al,ne,'N',NoParam0
or es:EmuStat,ACTIVE
jmp short OnOff0
NoParam0:pop es
stc
ret
off: and es:EmuStat,not ACTIVE
OnOff0: pop es
;======================
; Display Video Status
;======================
assume ds:code,es:nothing
x2c macro func,value,IncReq
mov di,offset Msg&value
mov al,Video&value
if IncReq
inc ax
endif
call func
endm
PutStat proc near
pushs <ds,es>
mov ds,cs:resident
testif EmuStat,ACTIVE,nz,PutStat0
mov word ptr cs:MsgEmu+1,'FF'
assume ds:bios,es:code
PutStat0:xor ax,ax
mov ds,ax
movp es,cs
cld
x2c h2c,Mode,0
x2c h2c,Page,0
x2c d2c,Cols,0
x2c d2c,Rows,1
x2c d2c,Scan,0
mov dx,offset MsgStat
pops <es,ds>
assume ds:code,es:nothing
puts proc
push ds
mov ah,9 ;Write string to standard output
movp ds,cs ;
int 21h ;
pop ds
clc
ret
puts endp
assume ds:bios,es:code
_d2c proc near
xor ah,ah
div dl
jalz _d2cQ
add al,'0'
mov es:[di],al
_d2cQ: mov al,ah
inc di
ret
_d2c endp
d2c proc near
irp i,<100,10>
mov dl,i
call _d2c
endm
add es:[di],ah
ret
d2c endp
h2c proc near
push ax
shr al,4
call h2c0
pop ax
h2c0 proc near
push ax
and al,0Fh
if_ al,le,9,h2c1
add al,'A'-'0'-10
h2c1: add al,'0'
stosb
pop ax
ret
h2c0 endp
h2c endp
PutStat endp
OnOff endp
;================
; Set Video Mode
;================
; DS = segment address of program segment prefix
; Return: CF if no valid paramter found
assume ds:nothing,es:nothing
SetMode proc near
mov dx,offset MsgBadVideo
mov bx,fcb
mov ax,[bx+3]
if_ al,e,' ',SetModeErr
if_ ah,e,'4',Set80x34
if_ al,a,'7',PutsErr
sub al,'2'
jb PutsErr
cbw
shl ax,1
mov bx,ax
mov ax,ModeTable[bx]
mov bh,ah
jmp short SetMode0
Set80x34:xor al,al ;80x34 (480 scan lines with 8x14 dot font)
mov bh,11h ;
SetMode0:pushs <ds,es,ax,bx>
mov ax,6300h ;Get DBCS vector
int 21h ;
cmp word ptr[si],0
pops <bx,ax,es,ds>
mov dx,offset MsgNoUSMode
je _SetMode
PutsErr:call puts ;Don't a MILD7's mode in DBCS env.
SetModeErr:stc
ret
;---
; AL = vertical resolution
; 00h 480 scan lines
; 01h 350 scan lines
; 02h 400 scan lines
; BH = character set to load
; 00h default font
; 11h 8x14
; 12h 8x 8
; 14h 8x16
_SetMode:jalz SetMode43h
mov ah,12h ;Select vertical resolution
mov bl,30h ;
int 10h ;
mov ax,3
jmp short DoSetMode
SetMode43h:mov ax,43h
DoSetMode:int 10h ;Set video mode
jbhz SetModeQ
mov ah,11h ;Text-mode character generator functions
mov al,bh ;
xor bl,bl ;
int 10h ;
SetModeQ:clc
ret
SetMode endp
;================
; Main Transient
;================
assume ss:stacks
init proc far
mov psp,ds
mov bx,5Ch+1
if_ <word ptr[bx]>,e,'IM',init0
mov fcb,bx
init0: call hello
call GetVect
call GetResident
mov di,81h
mov cl,[di-1]
xor ch,ch
jcxz ChkInst
mov al,'/'
cld
repne scasb
jne ChkInst
mov al,[di]
mov dx,offset MsgHelp ;If /? then display help and
if_ al,e,'?',PutRC ;exit with RC=0
or al,20h ;Convert to upper case letter
if_ al,e,'u',unload
mov MsgInvSw0,al
assume ds:code
mov dx,offset MsgInvSw
PutRC1: stc
PutRC: pushf
call puts
popf
RetRC: mov ax,4C00h ;Terminate with return code
adc al,al ;
int 21h ;
;---------
; Install
;---------
assume ds:nothing
ChkInst:mov cx,resident ;Is MILD7 installed?
jcxz ChkInst0 ; No...
callif OnOff,nc,RetRC
callif SetMode,nc,RetRC
call PutStat
clc
jmp RetRC
ChkInst0:mov ax,6F00h ;Video 7 Installation check
xor bx,bx ;
int 10h ;
mov dx,offset MsgAlready
if_ bx,e,5637h,PutRC1
mov ah,49h ;Free memory
mov es,ds:[2Ch] ; Segment of environment for process
int 21h ;
call install
callif OnOff,nc,TermStay
callif SetMode,c,TermStay
call hello
TermStay:mov dx,offset MsgInst
call puts
mov dx,(TSRSize+1Fh)/10h+code
sub dx,psp
mov ax,3100h ;Terminate and stay resident
int 21h ;
;--------
; Unload
;--------
even
HelloInd dw HelloQ
xPutRC1:jmp PutRC1
unload: mov cx,resident
mov dx,offset MsgNotInst
jcxz PutRC1
mov si,offset int10h
les di,_org10h
mov ax,es
mov dx,offset MsgBadVect
if_ ax,ne,cx,xPutRC1
assume es:code ;ES -> segment of resident
mov dx,offset MsgNoTSR
if_ es:psp,e,0,xPutRC1 ;Branch if installed as a driver
mov ah,0Fh ;Get current video mode
int 10h ;
if_ al,e,41h,unload0
if_ al,e,43h,unload0
if_ al,ne,5Bh,unload1
unload0:mov cs:HelloInd,offset hello
mov al,2 ;400 scan lines
xor bh,bh ;Load default font
call _SetMode
unload1:irp i,<10h,2Fh>
mov ax,25&i ;Set int i vector
lds dx,es:_org&i ;
int 21h ;
endm
mov ah,49h ;Free memory
mov es,es:psp ;
assume es:nothing ;
int 21h ;
call HelloInd
mov dx,offset MsgUnload
clc
jmp PutRC
init endp
code ends
;===============
; Stack Segment
;===============
stacks segment word stack'STACK'
dw 384 dup(?)
stacks ends
end init