Initial import from FreeBSD RELENG_4:
[dragonfly.git] / usr.bin / doscmd / emsdriv.S
1 ! Copyright (c) 1997 Helmut Wirth <hfwirth@ping.at>
2 ! All rights reserved.
3 !
4 ! Redistribution and use in source and binary forms, with or without
5 ! modification, are permitted provided that the following conditions
6 ! are met:
7 ! 1. Redistributions of source code must retain the above copyright
8 !    notice immediately at the beginning of the file, witout modification,
9 !    this list of conditions, and the following disclaimer.
10 ! 2. Redistributions in binary form must reproduce the above copyright
11 !    notice, this list of conditions and the following disclaimer in the
12 !    documentation and/or other materials provided with the distribution.
13 ! 3. The name of the author may not be used to endorse or promote products
14 !    derived from this software without specific prior written permission.
15 !
16 ! THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 ! IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 ! OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 ! IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 ! INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 ! NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 ! DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 ! THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
24 ! (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 ! THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 !
27 ! $FreeBSD: src/usr.bin/doscmd/emsdriv.S,v 1.2 1999/08/28 01:00:14 peter Exp $
28
29
30 !
31 ! This driver is needed for Expanded Memory emulation (EMS). A driver
32 ! is needed here, because EMS drivers are installed as DOS devices
33 ! with the name "EMMXXXX0" and programs look for such a device while
34 ! checking the existence of EMS. 
35 ! The driver is installed by CONFIG.SYS, it has no options. It uses
36 ! the emulator callback interrupt 0xff to initialize the EMS subsystem.
37 ! If EMS is not configured or if there is an error inside the emulator
38 ! the driver reports failure and does not install itself.
39 ! If all works, the driver changes the interrupt vector for int 0x67 to
40 ! point at itself. The resident part of the drivers simlpy routes calls
41 ! to int 0x67 to the correct subfunction of the emulator callback interrupt.
42
43 use16
44
45 .text
46 .bss
47 .data
48 .align 0
49
50         .org    0
51
52 NumFunc =       15
53
54 ! Emulator interrupt entry
55 EmulatorINT = 0xFF
56
57 ! Emulator EMS callback function
58 EMU_EMS         = 0x2
59 EMU_EMS_CTL     = 0
60 EMU_EMS_CALL    = 1
61
62 ! DOS print message
63 DOSMesg     = 0x9
64
65 cr      =       0xd
66 lf      =       0xa
67 eom     =       '$'             ! DOS end of string
68
69 EMSintnum = 0x67
70 Intoffset   =   (EMSintnum * 4)
71
72 .globl _main
73 _main:
74
75 driverhead:
76         .long   -1              ! link to next device driver
77         .word   0xC000          ! attribute word for driver 
78         .word   Strategy        ! ptr to strategy routine
79         .word   Interrupt       ! ptr to interrupt service routine
80         .ascii  "EMMXXXX0"      ! logical device name
81
82 reqhead:
83         .long   0
84
85 vectordone: 
86         .word   0               ! != 0 , if vector installed
87
88 FuncTable:
89         .word   InitDrv         ! initialize driver
90         .word   Noop            ! media Check 
91         .word   Noop            ! build BPB
92         .word   Noop            ! Ioctl
93         .word   Noop            ! read
94         .word   Noop            ! non destructive read
95         .word   Noop            ! input status
96         .word   Noop            ! flush input
97         .word   Noop            ! write
98         .word   Noop            ! write with verify
99         .word   Noop            ! output status
100         .word   Noop            ! flush output
101         .word   Noop            ! ioctl output
102         .word   Noop            ! open device
103         .word   Noop            ! close device
104         .word   Noop            ! removeable media check
105
106 Strategy:
107         seg cs
108         mov     [reqhead], bx
109         seg cs
110         mov     [reqhead+2],es
111         retf
112
113 Interrupt:
114         push    ax
115         push    bx
116         push    cx
117         push    dx
118         push    ds
119         push    es
120         push    di
121         push    si
122         push    bp
123         
124         push    cs
125         pop     ds
126
127         les     di,[reqhead]            ! load pointer to request header
128
129         seg es
130         movb    bl,[di+2]
131         xorb    bh,bh
132         cmp     bx, #NumFunc
133         jle     dointr
134         call    errorhandler
135         jmp     intrend
136
137 dointr: 
138         shl     bx,#1
139         call    [bx+FuncTable]
140         les     di,[reqhead]            ! load pointer to request header
141
142 intrend:
143         or      ax,#0x100               ! done bit
144         seg es
145         mov     [di+3],ax
146
147         pop     bp
148         pop     si
149         pop     di
150         pop     es
151         pop     ds
152         pop     dx
153         pop     cx
154         pop     bx
155         pop     ax
156         retf
157
158 errorhandler:
159         mov     ax,#0x8003              ! report error to caller
160         ret
161
162
163 ! This is done for all functions except init. It supports the different
164 ! methods for an EMS installation check described in the LIM EMS 4.0 spec
165 Noop:
166         call    installvector
167         xor     ax,ax
168         ret
169
170 ! The interrupt vector installed for int 0x67 points to this routine
171 intr67:
172         push    ax                      ! Save original AX
173         mov     ah, #EMU_EMS            ! Emuint function
174         mov     al, #EMU_EMS_CALL       ! Emuint subfunction
175         int     EmulatorINT             ! Call emulator for EMS
176         iret
177
178 installvector:
179         push cs
180         pop ds                  ! load DS to use local data
181         mov ax,[vectordone]
182         cmp ax,#0
183         jne isinstalled         ! already installed
184
185         push    di              ! save request header pointer
186         push    es
187
188         mov     ax, #0          ! write the new interrupt vector
189         mov     es, ax
190         mov     di, #Intoffset
191         seg     es
192         mov     [di], #intr67
193         seg     es
194         mov     [di+2], cs
195
196         pop     es
197         pop     di
198
199         mov ax,#1
200         mov [vectordone],ax
201
202 isinstalled:
203         ret
204
205 InitDrv:
206         push    cs
207         pop     ds
208         push    ax
209         mov     ah, #EMU_EMS            ! Emuint function
210         mov     al, #EMU_EMS_CTL        ! Emuint subfunction
211         int     EmulatorINT
212         cmp     ax,#0                   ! check if successful
213         je      Fail
214         
215         call    installvector
216
217         push    cs
218         pop     ds
219
220         mov     ah, #DOSMesg
221         mov     dx, #Success
222         int     0x21
223
224         seg es
225         mov     [di+14], #InitDrv       ! address break for driver
226         seg es
227         mov     [di+16], cs
228
229         xor ax,ax
230         ret
231
232 Fail:
233         push cs
234         pop ds
235         mov     ah,  #DOSMesg
236         mov     dx,  #Failure
237         int     0x21
238
239         seg es 
240         movb    [di+13],#0
241         seg es
242         mov     [di+20],cs
243         seg es
244         mov     [di+14],#0              ! address break == 0, no driver
245         seg es
246         mov     [di+16],cs
247         ret
248
249
250 Success:        
251         .ascii  "Doscmd EMS 4.0 driver installed"
252         .byte   cr,lf,eom
253
254 Failure:
255         .byte   cr,lf,lf
256         .ascii  "EMS emulation is disabled"
257         .byte   cr,lf
258         .ascii  "Driver not installed"
259         .byte   cr,lf,lf,eom
260
261         end