CA2265567C - A method and system for device virtualization based on an interrupt request in a dos-based environment - Google Patents

A method and system for device virtualization based on an interrupt request in a dos-based environment Download PDF

Info

Publication number
CA2265567C
CA2265567C CA002265567A CA2265567A CA2265567C CA 2265567 C CA2265567 C CA 2265567C CA 002265567 A CA002265567 A CA 002265567A CA 2265567 A CA2265567 A CA 2265567A CA 2265567 C CA2265567 C CA 2265567C
Authority
CA
Canada
Prior art keywords
dos
protected
mode
dos extender
extender
Prior art date
Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
Expired - Fee Related
Application number
CA002265567A
Other languages
French (fr)
Other versions
CA2265567A1 (en
Inventor
Joseph T. Friel
Andrew P. Weir
Current Assignee (The listed assignees may be inaccurate. Google has not performed a legal analysis and makes no representation or warranty as to the accuracy of the list.)
Creative Technology Ltd
Original Assignee
Creative Technology Ltd
Priority date (The priority date is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the date listed.)
Filing date
Publication date
Application filed by Creative Technology Ltd filed Critical Creative Technology Ltd
Publication of CA2265567A1 publication Critical patent/CA2265567A1/en
Application granted granted Critical
Publication of CA2265567C publication Critical patent/CA2265567C/en
Anticipated expiration legal-status Critical
Expired - Fee Related legal-status Critical Current

Links

Classifications

    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F13/00Interconnection of, or transfer of information or other signals between, memories, input/output devices or central processing units
    • G06F13/10Program control for peripheral devices
    • G06F13/105Program control for peripheral devices where the programme performs an input/output emulation function
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F9/00Arrangements for program control, e.g. control units
    • G06F9/06Arrangements for program control, e.g. control units using stored programs, i.e. using an internal store of processing equipment to receive or retain programs
    • G06F9/44Arrangements for executing specific programs
    • G06F9/455Emulation; Interpretation; Software simulation, e.g. virtualisation or emulation of application or operating system execution engines
    • G06F9/45533Hypervisors; Virtual machine monitors
    • G06F9/45558Hypervisor-specific management and integration aspects
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F9/00Arrangements for program control, e.g. control units
    • G06F9/06Arrangements for program control, e.g. control units using stored programs, i.e. using an internal store of processing equipment to receive or retain programs
    • G06F9/44Arrangements for executing specific programs
    • G06F9/455Emulation; Interpretation; Software simulation, e.g. virtualisation or emulation of application or operating system execution engines
    • G06F9/45533Hypervisors; Virtual machine monitors
    • G06F9/45558Hypervisor-specific management and integration aspects
    • G06F2009/45579I/O management, e.g. providing access to device drivers or storage

Abstract

A technique for providing device virtualization in an MS-DOS based operating environment (212), using an interrupt request (e.g., a non-maskable interrupt), is described. The technique includes executing an application on a processor within the MS-DOS based operating environment (212) and, when the application attempts to address the device to be emulated, causing a processor interrupt to occur. In response to the interrupt, the processor executes code representing the virtualization of a device. The code for servicing the interrupt and emulating the device are written in protected mode-code, stored in the extended memory area (114), and made available by making appropriate entries into the interrup descriptor tables (318) for the protected-mode context established for the DOS extender (410). The entries made into IDT
(318) for the protected-mode context established for the DOS extender are accomplished by intercepting communications between the DOS extender and the virtual control program interface (314).

Description

?CA 02265567 2000-05-23 63189-424 l A METHOD AND SYSTEM FOR DEVICE VIRTUALIZATION BASED ON AN INTERRUPT REQUEST IN A DOS-BASED ENVIRONMENT FIELD OF THE INVENTION 5 This invention generally relates to computer software and, more particularly, it relates to the use of an interrupt request for triggering device Virtualization services in a DOS- based operating system environment. BACKGROUND OF THE INVENTION 10 MS-DOS is Microsoft's 16-bit operating system which runs on PC-XT- and PC—AT—type personal computers (PCS). This operating system (OS) was originally developed for the Intel 8086 and 8088 microprocessors which operate in what is generally referred to as “real—mode”. Real—mode refers to the 15 way the microprocessor handles memory (i.e., providing the user with a single-tasking working environment in which programs can freely access system memory and input/output devices). It is noted that real-mode, by itself, does not include features such as memory management or protection. 20 Today's personal computers are equipped with more advanced processors from Intel, specifically the 80386, 80486, and Pentium, all of which are capable of running 8086- compatible code (real—mode). These processors, however, have a more advanced 32-bit protected—mode which provides hardware 25 support for multitasking, data security and virtual memory. Among other things, protected—mode allows access to more random access memory (RAM) than the 1 megabyte (MB) that the standard real-mode MS-DOS operating system permits (additional details described in King, A., “Inside Windows 95”, Microsoft Press, 30 pp. 33-43, 1994. ?10 15 20 25 30 CA 02265567 2000-05-23 63189-424 2 A typical memory configuration of a personal computer is shown in Figure 1. The memory configuration of Figure 1 shows a memory area 110 containing 640 kilobytes (K) of conventional memory. Because MS—DOS is designed for managing this conventional memory, an additional memory manager is not required. All MS—DOS based programs require conventional memory. The remainder of the standard 1 MB is referred to as the upper memory area 112 which comprises 384K of memory above the 640K of conventional memory. The upper memory area 112 is generally used by system hardware, such as a display adapter. Unused parts of the upper memory area 112 are called upper blocks (UMBs). On any PC, UMBs can be used for running device drivers and memory—resident programs as described below. An extended memory (XMS) area 114 is memory located beyond the 1 MB boundary on computers with 80286, 80386 or 80486 processors. Extended memory requires an extended—memory manager, such as HIMEM. A high memory area (HMA) 116 is approximately the first 64K of the extended memory area 114. The HMA 116 is a small address region, slightly less than 64K, above the 1 MB boundary that can be accessed by real—mode code. The address region of the HMA is from 10000Oh through 10ffefh. On a computer with extended memory, the setup program can install MS-DOS to run in the HMA 116. This provides more conventional memory to be available for other software programs. Another type of memory available, as shown in Figure 1, is known as expanded memory. An expanded memory board (EMS) 118 contains additional memory that some MS—DOS based applications can use. Most personal computers accommodate expanded memory. Expanded memory is installed on an expanded ?CA 02265567 2000-05-23 63189-424 3 memory board 118 and requires an associated expanded memory manager. Computer software programs use expanded memory 64K at a time by addressing a part of the upper memory area 112 known as the EMS page frame. Because an expanded memory manager 5 gives access to a limited amount of expanded memory at a time, using expanded memory is slower than using extended memory. A conventional software program such as EMM386 can simulate expanded memory using extended memory for programs that require it. 10 As MS—DOS matured through the 1980s, much of its functionality was added in the form of device drivers. As set forth in the Encyclopedia of Computer Science, Third Edition, IEEE Press (1993) a device driver is a program or Subprogram that is written to control either a particular hardware device 15 or another software routine. This low—1evel software program is loaded into memory after the operating system boots and remains in memory for the duration of the operating session. As mentioned, the device driver can deal directly with the hardware of a particular device. The device driver is capable 20 of responding to hardware and software interrupts and interfacing to the operating system through an established MS- DOS device driver protocol in order to serve as an interface between such hardware or software and the operating system (described in “Microsoft MS-DOS 6 User's Guide”, Microsoft 25 Corporation, pp. 87-89, 1993. It should be noted that device drivers are generally limited in size to 64K bytes. In addition to device drivers, MS—DOS also uses memory—resident software programs, often referred to as terminate—and—stay—resident programs (TSRs). These programs 30 are executed like normal software programs, but after termination, a portion of the program remains installed in memory in order to monitor and/or service hardware or software ?10 15 20 25 30 CA 02265567 2000-05-23 63189-424 4 interrupts. TSRs can also interface with the operating system in a limited sense, but they do not use the MS—DOS device driver protocol. Both device drivers and TSRs are typically real—mode code and reside in memory below the MS—DOS 1 MB limit. In many cases, these resident software programs reside within the conventional 640K of memory which is normally used by MS—DOS to load and execute programs. As mentioned above, they may reside above the conventional 640K in the upper memory area 112 when, for example, a memory optimizing routine is executed such as MemMaker (additional details are provided in MS—DOS User's Guide, beginning on page 131). In this case, the driver or TSR would be placed into the upper memory area 112 with a link to its location placed in the 640K conventional memory 110 to indicate its memory location in the upper memory area 112. Even so, as more and more device drivers and TSRs are loaded into a system, the maximum allowable memory area for MS—DOS programs, drivers and TSRs is rapidly reduced. To further illustrate the functional interrelationships of MS—DOS, device drivers, hardware, etc., Figures 2 through 4 illustrate the evolution, from a functional perspective, beginning with the original MS-DOS real-mode environment up to present day environments allowing for protected—mode and DOS extenders. It is noted that the functional interrelationships shown in Figures 2 through 4 are well known to those of ordinary skill in the art and well documented as well; therefore, each figure is only briefly A more comprehensive treatment of DOS extenders and EXTENDING DOS, A described. their evolution is provided in Duncan et al., Programmer's Guide to Protected—Mode DOS, 2“ Edition, Addison- (1992). Wesley ?1O 15 20 25 30 CA 02265567 2000-05-23 63189-424 5 Turning to the figures, Figure 2 shows a block diagram of a conventional DOS operating environment with no memory management services. This operating environment is The hardware 210 sends an interrupt request, represented by the similar to that used in the 8086- and 8088—based PCS. dotted line 211, to the DOS operating system 212 which is initially serviced by the DOS Interrupt Vector Table 213. Based on the entries in Interrupt Vector Table 213, the interrupt request can be directed to the DOS OS 212, device drivers 214, TSRs 216, etc. Similarly, software interrupts generated by programs 218 are serviced by the DOS Interrupt Vector Table 213 and directed as appropriate. As mentioned above, with the release of more powerful Intel processors in the late 1980s, special “extensions” to the standard MS—DOS operating system were developed to allow MS-DOS programs to easily access computer memory that would not otherwise be addressable using real—mode code. These extensions (i.e., device drivers) to the operating system take advantage of the protected—mode features of the 8OX86 processors while allowing MS—DOS to continue executing in real- mode. as a minimum, These device drivers implement, memory management services referred to as EMS and XMS services. These services allow software programs to store and retrieve large amounts of data from the memory pool above the 1 MB boundary. However, they do not allow software programs to occupy this memory for execution purposes. The well known programs provided by Microsoft to implement this functionality are called HIMEM.SYS and EMM386.EXE. Continuing with the figures, Figure 3 shows a block diagram of a conventional DOS operating environment with conventional memory management services 312 installed for managing the extended memory area 114. This operating ?10 15 20 25 CA 02265567 2000-05-23 63189-424 6 environment is similar to that used in 80286—based PCS through Pentium-based PCS. 310 executes above the DOS OS 212. As shown in Figure 3, a protected—mode OS An interrupt request 311 generated in this environment passes first into the protected- mode OS 310 allowing for higher level management. As shown, the interrupt request 311, based on entries in an Interrupt Descriptor Table (IDT, described in more detail below), may be directed to memory management services 312, to the Virtual Control Program Interface (VCPI) 314, or to the default DOS service via the DOS Interrupt Vector Table 213 as in the Figure As shown, 2 type systems. the protected-mode OS includes the IDT 318 as well as a GDT 320. Additional details of the operation of the VCPI are described in the Virtual Control (1989). Program Interface specification, Version 1.0, Concurrent with the development of these memory extensions was the development of DOS extenders. Figure 4 shows a block diagram of a conventional DOS operating environment with memory management services 312 installed and a DOS extender 410 running. DOS extenders are low-level software components that allow programs to be executed in protected—mode under MS—DOS. The DOS extender 410 allows protected—mode applications 412 to communicate with hardware and the OS and vice versa. These programs can use the vast amount of memory above 1 MB to execute code as well as to store and retrieve data. However, the DOS extenders do not allow executable code to permanently reside in memory above the 1 MB boundary; the DOS extenders rather, upon switching into protected-mode, can temporarily copy executable code into the extended ...._ . ...._....................u.........«..................«..«»..u.............‘..._‘.....m.,\... ?10 15 20 25 30 CA 02265567 1999-03-10 WENUS 1 9 MAR’ 1:193 -7- memory area for purposes of execution, but upon termination, it no longer exists in extended memory. Even so, the DOS extenders allow programs to apply a much simpler and much more powerful programming model. DOS extenders achieve their task by switching the processor into protected-mode while running the program, and switching the processor back to real—mode when the program completes. The DOS extenders also switch the processor in and out of real-mode during the program execution when MS-DOS functions need to be To do this, the DOS extender must be in complete control of the system. Thus, a new called, or when device drivers or TSRs need to run. protected-mode operating environment is created by the DOS extender. As shown in Figure 4, the newly created protected-mode operating environment created by the DOS extender 410 includes its own IDT 418 andGDT 420. to real mode it then uses system IDT 318 and system GDT 320. It is noted, however, that when the DOS extender switches back In systems with memory management enabled, as shown in Figures 3 and 4, the device drivers that provide these services create their own protected-mode environment and already have MS-DOS running as a real—mode task. Therefore, they provide contention management services to negotiate memory allocation and mode switching between This contention management is implemented If a DOS extender 410 themselves and DOS extenders. by all memory managers today via the VCPI 314. determines that a VCPI 314 is present in a system, it uses this interface to acquire its protected-mode context and to perform its mode switching (real versus protected). In most cases, the DOS extender 410 also allocates all of its required program memory through the VCPI 314. With this evolution in mind, as available memory, as well as processing power, continue to increase, it is desirable to make efficient use of these computing resources to provide device virtualization, thereby reducing the amount of hardware necessary to provide desirable features. .- . r-~:«'«'r- 2,205: _- :<,.~.~..-: ECTlUS97l15813 ?10 15 20 25 30 CA 02265567 1999-03-10 mxus 97/ 15 81 3 |pEA/Us . 3 MAR 1098 -8- The 80386 and later processors do generally provide for hardware virtualization by allowing certain instructions to be "trapped::_Specifically, if a program executes an "IN" or "OUT" (I/O) instruction, a General Protection Fault handler can be invoked to decidewhether or not to let the IN/OUT execute and/or whether or not to emulate the presence of some hardware. This "I/O Trapping" can be applied to any process running below processor privilege level (or ring)0. Unfortunately, most DOS extenders (Rational Systems’ DOS4GW for example) run at ring 0, thus they are not subject to the 80386 I/O trapping mechanism. In addition to the 80386 I/0 trapping mechanism, at least one hardware manufacture has used a combination of external hardware interrupts and software to replace the functions of more costly hardware. Specifically, Advanced Gravis has used a technique which combines a Non—Maskable Interrupt (NMI) and a DOS TSR to virtualize hardware. Although this technique provides hardware virtualization for applications executing in real-mode, it does not provide virtualization for applications executing under a DOS extender, since there is no predetermined method for the OS to direct the interrupt services of the DOS extender. There is, therefore, a real need to provide an efficient way of performing device virtualization which is also accessible by DOS extenders. SUMARY OF THE INVENTION The present invention involves a technique for providing device virtualization in a DOS based operating environment including thesteps of executing an application, under a DOS extender, on a processor within the DOS—based operating environment, where the application executes within a protected—mode context created for the DOS extender and the protected—mode context includes an interrupt descriptor table (IDT). application addresses a predetermined address related to the device to Additionally, a processor interrupt is generated when the be emulated and, responsive to the processor interrupt, an appropriate entry in the IDT associated with the protected-mode IIEIDEDIQEI ?10 15 20 25 30 CA 02265567 2000-05-23 63189-424 9 context of the DOS extender is referenced. In accordance with the invention, the DOS extender’s IDT is patched at run—time to vector to device emulation software, thereby allowing the processor to execute computer code designed to emulate the device even though the DOS extender was not present at boot- time. The invention may be summarized according to a first broad aspect as a method of providing device virtualization to an application running under a DOS extender within a protected- mode context created for said DOS extender within a DOS-based operating system environment of a processor at run-time, said protected—mode context created for said DOS extender including an interrupt descriptor table for said DOS extender (DOS extender IDT), comprising the steps of: storing device emulation code at a predetermined address in a memory accessible to said processor; detecting startup of said DOS extender; upon detection of startup of said DOS extender, patching said DOS extender IDT to include a vector to said device emulation code for a predetermined interrupt; and when said processor detects said predetermined interrupt during execution of said application, said processor referencing said vector to said device emulation code patched into said DOS extender IDT. According to another aspect the invention provides a system which provides device virtualization to an application running under a DOS extender in a DOS—based operating system environment of a processor, said DOS extender executing within a protected—mode context created for said DOS extender within said DOS—based operating system environment of said processor at run-time, said protected—mode context created for said DOS ?10 15 20 25 CA 02265567 2000-05-23 63189-424 9a extender including an interrupt descriptor table for said DOS extender (DOS extender IDT), said system comprising: device emulation code stored at a predetermined address in a memory accessible to said processor; a detection program which detects startup of said DOS extender; and a driver which operates in said protected-mode context of said DOS extender and which, upon detection of startup of said DOS extender by said detection program, patches said DOS extender IDT to include a vector to said device emulation code for a predetermined interrupt, whereby, when said processor detects said predetermined interrupt during execution of said application, said processor references said vector to said device emulation code patched into said DOS extender IDT by said driver. BRIEF DESCRIPTION OF THE FIGURES Figure 1 is a block diagram of a conventional memory configuration of a personal computer. Figure 2 is a high—level functional block diagram of a conventional DOS operating environment. Figure 3 is a high—level functional block diagram of a conventional DOS operating environment with memory management services installed. Figure 4 is a high—level functional block diagram of a conventional DOS operating environment illustrating the functional relationships of DOS with memory management services and DOS extenders. Figure 5 is a high—level functional block diagram of a DOS operating environment as it relates to an exemplary embodiment of the present invention. ............... ......_...—.-.—...-a-us-an-—-an-»—-u........._~............. .. ..,..,....,...._ Innluuqu-um-mm-». ..... . . ?CA 02265567 2000-05-23 63189-424 9b Figure 6 is a flow diagram of the initialization operation, at boot time, of an exemplary embodiment of the present invention. Figure 7 is a flow diagram of the operation of an 5 exemplary embodiment of the present invention, at run time, to provide compatibility with DOS extenders. ?l0 l5 20 25 CA 02265567 1999-03-10 ggr?as 9%/15,813 PEA/Us 1 9 MAR1998 -10- DETAILED DESCRIPTION OF THE EXEMPLARY EMBODIMENTS Overview As mentioned in the Background section, device virtualization, in general, is known. Unfortunately, when running in the context of DOS extenders (e.g., Rational Systems’ DOS4GW), device drivers cannot take advantage of the I/O trapping mechanism, nor can they take advantage of Advanced Gravis technique mentioned above in the Background section. Because many present day applications use DOS extenders for various reasons, a device virtualization technique should be accessible by applications running “under” DOS extenders. Generally, the present invention provides device virtualization, in an MS—DOS based operating environment, by way of aninterrupt request (e.g. non—maskable interrupt) for applications running with or without a DOS extender. The present invention dynamically extends its device virtualization capabilities to applications running under DOS extenders by intercepting communications between the DOS extender and the VCPI at run time. In particular, when an executing application requests the use of a particular device (e.g., requesting a predetermined I/O address), a processor interrupt request is generated. In response to the interrupt request, the device virtualization code forthat particular device can be accessed and executed even for It is noted that, in the exemplary embodiment, the present invention relies on the presence of a applications running under DOS extenders. memory manager, or an equivalent thereof, to provide for a primary protected—mode operating environment including the system IDT and GDT. Figure 5 is a block diagram illustrating the functional relationship between conventional operating system components in a typical MS-DOS environment as described in the Background section with 5. r. .rm,!1‘."k’.'T\ ?10 15 20 25 30 CA 02265567 2000-05-23 63189-424 11 reference to Figures 2 through 4 and an exemplary embodiment of the present invention. As shown in Figure 5, the present invention functionally represents a new functional layer working in conjunction with the protected—mode OS 310. This new layer is referred to, for purposes of this specification, as VIVO driver 510. Essentially, the VIVO driver 510 becomes an extension of the protected-mode operating system that supervises MS—DOS and DOS extenders instead of simply becoming an extension of MS-DOS itself, as is the case with standard device drivers and TSRs. In the exemplary embodiment of the present invention, in addition to VIVO driver 510 which represents a driver designed to provide the device virtualization services, a VIVO TSR 520 is provided to aid in the dynamic extension of the services by the VIVO driver 510 for use with DOS extenders 410. The present invention includes loading protected—mode executable code, including an interrupt service routine and device virtualization code, into memory, and entering the associated interrupt service vector directly into the protected-mode operating system's interrupt descriptor table (IDT) 318. The use of IDTs is well known and additional details of descriptor addressing are described beginning on page 41 of the Windows '95. Additional teachings on the use of IDTs can be found in Microprocessors, Intel (1989). Briefly, the protected-mode IDT 318 determines interrupt vectoring instead of the DOS Interrupt Vector Table 213 even when the protected-mode OS 310 is running real—mode code. In many cases, such as MS—DOS OS calls, the services indicated by the IDT entries in IDT 318 simply pass control to the real—mode services indicated by the DOS interrupt vector table that ?CA 02265567 2000-05-23 63189-424 lla were installed by MS-DOS. As well as being faster and more efficient than real-mode interrupt handlers, using the protected-mode IDT 318 makes the services of the present invention unconditionally available to the system whether it is running in real— or protected-mode. ?10 15 20 25 30 CA 02265567 1999-03-10 IPEA/US 1 9 MAR 1998 -12- ‘ Continuing, the present invention, by way of the VIVO TSR 520, uses the VCPI 'Get Protected—mode Interface’ real—mode call (Int 67, function deolh) to force all of the DOS extender’s 410 subsequent VCPI 314 protected-mode "far calls" to "pass through} the VIVO driver 510. It is noted that the DOS extender 410 at startup to acquire a protected-mode context. 'Get Protected—mode Interface’ is used by a when it is running under the (IDT 418, GDT 420). At the VIVO driver 510 installs its interrupt service vector the VIVO driver 510 intercepts these far calls, context of the DOS extender’s protected-mode OS this point, into the DOS extender’s IDT 418 making the VIVO driver's device virtualization service available to the DOS extender 410 (and its applications) until it terminates. Although the present invention is designed to operate using most any interrupt request, the exemplary embodiment of the present (NMI) as the interrupt request It is noted that, the NMI has been used by system motherboard logic to or by I/O devices to ndtify the operating system of some "unrecoverable" error. invention uses the non—maskable interrupt for triggering the device virtualization routine. historically, notify the operating system of a RAM (memory) parity error, however, the RAM parity no longer exists and I/O devices do not A typical DOS extender’s NMI handler, simply Today, implement NMI generation. however, not knowing specifically how to handle such an event, re—boots the system rather than "passing-down" the interrupt to the currently installed DOS handler as it would do with a normal interrupt. Therefore, unlike other interrupt services, an NMI interrupt service routine installed under DOS would most likely be ignored by an application running under a DOS extender. Description of Exemplary Embodiment Although illustrated and described below with reference to the present invention is nevertheless not Rather, modifications may be made in the details within the scope and range of certain specific embodiments, intended to be limited to the details shown. various equivalents of the claims and without departing from the spirit of the invention. unIIn¢O!§EET . For/us97/15911 ?10 15 20 25 30 CA 02265567 1999-03-10 I pgwg 1 9 MAR 1993 -13- Referring back to Figure 5, in operation, when an interrupt request 311 (e.g., NMI) is generated, the protected-mode IDT 318 directsthe flow of operation to the appropriate service routine based on the entries therein. If the interrupt is not intended for the VIVO driver 510, then the interrupt is passed on to the normal flow of operation. When the VIVO driver 510 of the present invention is present with a DOS extender 410 running, the interrupt request is not passed directly to the DOS extender 410. Rather, if the interrupt request is intended for the VIVO driver 510, the VIVO driver 510 acts on the request directly. If the request is not for the VIVO driver 510, then control is passed to the DOS extender 410, and the DOS extender 410 handles it in its normal way. It is noted that, in the exemplary embodiment of the present invention, because the NMI is used, the devicevirtualization can be performed immediately following the "faulting" instruction (i.e., the instruction which caused the NMI). Turning to the generation and installation of the present invention, after the computer code embodying the present invention is written, it is compiled/assembled and linked, in the exemplary embodiment, as zero address—based, non—re1ocatable, flat—model, 32—bit The computer code embodying the present invention It is noted that, in preparing the computer code embodying the present invention, protected- protected-mode code. is then saved as a standalone binary file. mode code is required (at least at the NMI service entry point) since the protected mode IDT’s vectoring mechanism does not allow vectoring to real-mode (or virtual 8086) code. It is also noted that, although some real-mode code is required, the exemplary embodiment of the present invention is implemented using almost all protected-mode code since it is more efficient for vectoring and execution and can be completely located in extended memory, thereby avoiding memory—hungry DOS real-mode applications. Basically, the VIVO driver 510 includes the device virtualization code for emulating the particular device and it includes the code minute SW5‘ PCT/us9%/15812 ?K) 10 15 20 25 30 CA 02265567 1999-03-10 IPEA/US 1 9 HAR 1998 -14- necessary to receive, at run time, the re—directed "far calls" from the DOS extender 410, make the appropriate entries in the IDT 418, and pass control onto the VCPI 314. It also includes the Int 67 handler which is used to reflect the VCPI Get Protected-Mode Interface call return into the VIVO TSR 520. suitable for use with the present invention is included as Appendix A. An exemplary implementation of VIVO driver 510 The installation and operation of the present invention is described with reference to the flowcharts in Figures 6 and 7. Referringto Figure 6, at boot-time, in the exemplary embodiment of the present invention, an MS-DOS initialization program (e.g., ssinit.com) allocatesa predetermined amount of the extended memory area 114 above the HMA 116using an extended memory (XMS) interface reference, step 610. An exemplary implementation of ssinit.com suitable for use with the presentinvention is included as Appendix B. The predetermined amount of memory,in the exemplary embodiment of the present invention, is the size of the32bit protected—mode code file. Additionally, in the exemplary embodiment, the allocated memory is below the 4 Megabyte boundary. Then, the allocated memory, using the XMS interface, is locked and the physical address is saved. Subsequently, the code embodying the present invention is copied into the allocated portion of extended memory, step 612. Appropriate entries are made into the protected-mode IDT 318 and GDT 320to allow the associated hardware or software interrupt to vector directly to the 32—bit service entry point(s) in extended memory, step614. It is noted that since the interrupt vectoring is done at the protected-mode level, the 32-bit services are always available and can be initiated by the protected-mode OS 310 without explicitly performing any time—consuming mode switching. More specifically, steps 612 and 614 are accomplished as follows: 1 mereuse srss;':"5 POTIUS97/15813 ?CA 02265567 1999-03-10 “CW8 9 7/ 15 81 3 IPEA/US 1 9 HAR1998 -15- The protected—mode code file embodying the present invention is opened and a 1 kbyte portion of the code is loaded into local memory.In the exemplary embodiment of the present invention, this first portionof the code is loaded because it has variables that need to be 5 initialized at predetermined offsets which can only be determined at this stage of loading the program (e.g., configuration parameters). Next, the VCPI "Get Protected-mode Interface" call (Int 67h, function deolh) is invoked and three selectors and an entry point offsetare returned. The three selectors and the entry point offset are copied 10 into a predetermined offset in the first portion of the protected—mode code. Also, the segment and offset of a portion of the MS—DOS initialization code is copied into a pre—determined offset in the first portion of the protected—mode code. This referenced portion of the MS-DOS initialization code remains resident after the MS-DOS initialization 15 code terminates and the protected—mode code, in the exemplary embodiment, will need to know where it is because it is essentially a shared dataspace used by the VIVO TSR 520 and the VIVO driver 510 to communicate. Next, the first portion of the protected—mode code is copied 20 into the allocated extended memory (e.g., using an XMS interface) andthen the rest of the protected—mode code embodying the present invention is copied into extended memory in the same manner. Next, the linear addresses for the protected—mode system IDT 318 and system GDT 320 and the physical address for the Page Directory 25 (using standard 386 instructions) are obtained and saved. A protected- mode initialization program (e.g., a DOS4GW executable) is spawned and the physical address of the allocated Extended Memory, GDT and IDT linear addresses, as well as the Page Directory physical address, are passed thereto. An exemplary implementation of the DOS4GW executable 30 suitable for use with the present invention is included as Appendix C. The functions of the protected—mode initialization program, in the exemplary embodiment of loading the present invention, are to: ?10 K l5 20 25 30 CA 02265567 1999-03-10 ac?/us 9%/15:12 JPEA/US 1 9 MAR 1998 -15- 1) Make three entries at the top of the protected mode Os's GDT 320. The first entry is a 32-bit code selector with a linear address based at the beginning of the allocated Extended Memory. The second entry is a data selector to alias the first entry. The third entry is a 32- bit data selector that is based at linear address 0 and has a maximum size (or limit). 2) Save the selector base of the entries made in step 1. 3) Make an entry into the protected mode OS's IDT 318 for vector 02h (the NMI vector). selector base saved above with an offset of zero This vector uses the (in the exemplary embodiment, the NMI entry point in the 32-bit code). 4) Save the original Int 67h vector. 5) Make an entry into the protected mode Os's IDT 318 for vector 67h (the Int 67 vector). This vector uses the selector base saved above with an offset of eight (the Int 67h intercept entry point in the 32-bit code). 6) Then, return control to the MS-DOS initialization program. Finally, the MS-DOS initialization program terminates, leaving a relatively small program in memory -— referred to above as the VIVO TSR 520. initialization program termination is a well known technique to those of The general technique of leaving a TSR in memory upon ordinary skill in the art. the VIVO driver 510 is linked into the VCPI service/control chain via the IDT 318 for Interrupt 67h so By way of the Int 67h entry, that the hooks are present for the present invention to extend its functionality to DOS extenders 410 when they initialize. It is noted that Interrupt 67h is a $9805‘: ?10 15 20 25 30 CA 02265567 1999-03-10 IPEA/US 1 9 MAR 1998 _.]_'7._ control function interface to the EMS 118 and VCPI 314. 67h handler (VIVO driver 510) and VIVO TSR S20 act upon VCPI functions, This Interrupt and then pass control to the normal Interrupt 67h handler installed by the protected—mode os. At this point, the protected—mode OS 310 is configured such that hardware virtualization is available to all real—mode programs and drivers. There are also now hooks in place to allow for the extension of the device virtualization service to applications running under DOS extenders. It is noted that, in the exemplary embodiment of the present invention, although the hooks are put in place during boot time, the extension of the device virtualization services to applications running under DOS extenders is completed at run—time. This is an important aspect of the present invention becomes it allows the present invention to avoid many of the drawbacks of the prior art techniques. It is noted that, although the above—described initialization process is performed using a combination of the Ms DOS initialization program and the protected-mode initialization program, inan alternate embodiment, all of the initialization functions performed by the MS DOS initialization program can be performed by the protected- mode initialization program. To do so, the MS DOS initialization program needs to pass an extra parameter to the protected—mode initialization program. The extra parameter is the real—mode address of the shared data space within the DOS initialization program. Continuing, the way in which the VIVO code of the present invention extends its functionality to DOS extenders via the Interrupt 67h handler is described with reference to the flowchart of Figure 7. As shown in Figure 7, after having established the VIVO TSR 520, it is triggered when, at run time, the DOS extender 410 calls the VCPI "Get Protected—Mode Interface" function, step 712, via Int 67h. At this point, the DOS extender 410, initially in real—mode] expects to acquire the protected—mode far—call entry point to the VCPI 314. This entry point is used For/us9%/15813 ?CA 02265567 1999-03-10 ' 9 3 IPEA/US 1 9 MAR 1998 -18- by the protected-mode OS created by the DOS extender 410 to communicate directly with the VCPI 314 without invoking software interrupts and without switching to real mode. However, the VIVO TSR 520 of the present invention, having been passed control, indirectly, by the VIVO 5 driver 510, at this point gives the DOS extender 410 an entry point tothe VIVO driver 510, step 714. It is noted that, in the exemplary embodiment of the present invention, the VIVO TSR S20 relies on the presence of a VCPI 314, or equivalent thereof, for cooperation with DOS extenders 410. 10 By providing DOS extender 410 with an entry point into the VIVO driver 510 rather than the actual VCPI entry point, the DOS extender 410 will now pass through the VIVO driver 510 on subsequentlgarcalls. When the DOS extender 410 makes these VCPI “far calls,” the system is in the DOS extender’s IDT/GDT protected-mode context. As 15 such, when the VIVO driver 510 intercepts the VCPI far—calls, it makes 9 its own interrupt vector entries into the DOS extender’s protected-mode OS IDT 418, step 716, similar to that which was done for the native protected—mode OS 310. After making the appropriate entries, the VIVO driver 510 then passes control to the actual VCPI 314 via the previously 20 saved VCPI protected-mode far—call entry point, step 718. More specifically, steps 714, 716 and 718 are accomplished as follows: The VIVO driver 510 intercepts the Get Protected—Mode Interface call at the Int 67h entry point (all other Int 67h calls are 25 passed through to the default handler). The VIVO driver 510 saves thereal—mode return address for the DOS extender 410 into the shared dataspace. It then changes the real—mode return address (stored on the processor stack) so that, when the actual VCPI service completes, control will pass to the VIVO TSR 520. So, essentially, all Int67h 30 calls still get processed by the default handler except that a Get Protected—Mode Interface call causes the change of the real—mode return address, by the VIVO driver 510, prior to being processed by the default handler. It is noted that, in an alternate embodiment, the function 35 of intercepting the initial Int 67h call from the DOS extender 410 may be 02.950020 SHEET ?l0 15 20 25 30 CA 02265567 1999-03-10 IPEA/US 1 9 MAR 1998 -19- performed by vxvo TSR 520. when the present invention runs under a memory manager, such as QEM by This may be problematic, however, because Quarterdeck Office Systems, the memory manager does not pass the VCPI Int 67h calls through the DOS Interrupt Vector Table, but rather, fieldsall VCPI Int 67h calls in protected mode via the IDT 318. Continuing with the exemplary embodiment, in the case of the Get Protected—Mode Interface call, control is then passed to the VCPI 314 which performs its service. The VCPI 314 returns control, via the new return address, to the VIVO TSR 520. context has been setup in the DOS extender’s data space. At this point, a page table The VIVO TSR 520 then makes additional page entries so that the VIVO driver 510 is The VIVO TSR 520 then copies the three selectors being passed back to the DOS valid within the DOS extender’s protected-mode context. extender 410 into the shared data space as well as the VCPI far call Next, the VIVO TSR 520 copies its own three selectors It then alters the VCPI entry offset (in register ebx) to 16, which is the offset into the VIVO driver 510 for the VCPI far call intercept. Finally, it returns control to the original real—mode return address entry offset. (described above) into the DOS extender’s return data space. (the DOS extender 410) saved above in the shared data space. At this point, all VCPI far calls made by the DOS extender 410 now pass control to the VIVO driver 510 within the context of the DOS extender’s new protected-mode OS. These calls include allocating extended memory for the DOS extender application and (temporarily) switching back to real-mode to service DOS interrupts and DOS OS calls. Whenever a VCPI far call is made, an interrupt entry is made in IDT 418 by VIVO driver 510. With this completed, device virtualization (e.g., hardware virtualization) services are available to the DOS extender’s protected- mode application program as well as to the normal DOS real—mode programs (i.e., VIVO driver 510 is accessible by programs running under DOS extender), step 720. ?"f" i‘*.'-"TN ,, 4 'P9‘§’~.T%‘3'*’? ~... PCT/us97/15313" ?10 15 20 25 30 CA 02265567 l999-03- 10 ‘ |pEA/Us 1 9 MAR 1998 "-20- The VIVO driver 510 of the present invention, like other device drivers and TSRs, implements software services for hardware interrupt events. However, the VIVO driver 510 in accordance with the present invention is different than standard MS—DOS device drivers andTSRS. driver 510 of the present invention can permanently reside above the 1 As such, the VIVO driver 510 does not compete for valuable memory space with standard MS—DOS programs For example, the memory-resident, executable code of the VIVO MB memory boundary and above the HMA 116. and other device drivers and TSRS. Moreover, the VIVO driver 510 is not limited to the 64K restriction of a typical device driver allowing for applications significantly larger than 64K which is particularly useful when, for example, one desires to emulate hardware with software. Commercial Embodiment A commercial embodiment in accordance with the present In this commercial embodiment, a VIVO driver is used to perform the function of invention is the Ensoniq® Soundscape” sound card VIVO drivers. hardware which previously existed on a sound card. By replacing the hardware with a VIVO driver, the space consumed and cost of the sound card are significantly reduced. -In operation, when an application requests access to the sound card, the request is directly processed by the VIVO driver and the functionality of that hardware element is performed in software rather than hardware. This is possible, in part, because present generation microprocessors (e.g., Pentium) are so powerful that they typically have considerable idle time which can be used to execute the VIVO driver, which appears like an application, without a noticeable delay in other necessary processing. This is only one example of how the use of a VIVO driver provides substantial advantages to not only optimizing conventional memory space but also optimizing the size and cost of an auxiliary computer card. In particular, in the commercial embodiment, if an application attempts to address the sound card in the processor I/O address space, normally 220h through 22fh, an NMI is generated. As a result, the VIVO v ~15: ye‘:-.g=‘-rq -$1?’ ;.- ‘ v‘$'..5*:$?:.'.3§~ ‘-“ ‘~" " W ecms97/1581} ?CA 02265567 l999-03- 10 W0 98/1 1489 PCT/US97/ 15813 -21- driver performs functional emulation of various hardware previously residing on the card (e. g., the Sound Blaster) in response L0 I/O writes and, during certain I/O reads, the handler alters the hardware I/O return value (in the Intel 386, register EAX) in order to emulate or virtualize the presence of the hardware in the system. Since the commercial embodiment of the present invention optionally alters the processor register state, it is necessary that the NMI service routine execute immediately following the faulting I/O instruction. Although illustrated and described above with reference to certain speci?c embodiments, the presentinvention is nevertheless not intended to be limited to the details shown. Rather, various modi?cations may be made in the details within the scope and range of equivalents of the claims and without departing from the spirit of the invention. ?W0 98/1 1489 -------u... «.-....--.—----.-.-.-....-.-..-.~.a—-.........-......-...-..-.-.‘--—.—.aa-.-a-....—.-......¢-on-..-. CA 02265567 1999-03-10 PCT/US97/15813 -22- APPENDIX A The port mapping for the I/0 hand1ers is as fo11ows ... BasePort+0Oh IoMpuData BasePort+01h Iompucstat wavePort+00h Iowss wavePort+O1h Iowss wavePort+O2h Iowss wavePort+03h Iowss wavePort+04h IoCdAddr wavePort+0Sh Iocdoata wavePort+06h IoPass wavePort+07h IoPass 220h IoPass 22lh IoPass 222h IoPass 223h IoPass 224h IoPass 225h IoPass 226h IoSb1Reset 227h IoPass 228h IOFmAStat 229h IoFmData 22ah Iosb1Data 22bh IoPass 22ch IoSb1Cstat 22dh IoPass 22eh Iosb1Rxrdy 22Fh IoPass 388h IoFmAstat 389h IoFmData 38ah IoPass 38bh IoPass The I/0 handiers are 32-bit NEAR rocedures that are ca11ed from the stub code. They w111 a11 assume t e fo11owing register conventions. Entry: cs — I/0 hand1ers' code se1ector ds — I/0 hand1ers' data se1ector ah — xoxxxxxxb if the "fau1ting" I/0 cyc1e was a read, xlxxxxxxb if it was a write a1 — the write va1ue if the "fau1ting" I/0 cyc1e was a write, otherwise undefined esi - offset to the Soundscape hardware structure Exit: a1 - set to the prescribed return va1ue if the fau1ting I/0 cyc1e was a read, otherwise preserved A11 other registers wi11 be preserved by the I/0 hand1ers. .386p IF wIN_coDE inc1ude vmm.inc inc1ude debug.inc_ inc1ude sndscape.1nc .x1ist .1ist EXTRN gpSSI: owono ELSE .MODEL f1at ENDIF INCLUDE vivo.inc EXTRN _synth_init: NEAR EXTRN _synth_process.MIDI: NEAR EXTRN _synth_a11_notes_off: NEAR SUBSTITUTE SHEET (RULE 26) ?CA 02265567 1999-03-10 W0 98/1 1489 -23- EXTRN _synth_set_MT32: NEAR EXTRN _fm_process: NEAR EXTRN _synth_update: NEAR EXTRN _otto_init: NEAR EXTRN _otto_io_page: NEAR EXTRN _otto_io_read: NEAR EXTRN _otto_io_write: NEAR EXTRN _otto_io_jam: NEAR EXTRN _MT32: BYTE EXTRN _num.§ctive_voices: BYTE EXTRN _fm_array: BYTE ; the soundB1aster commands to emu1ate DACIO-CMD EQU 010h DACDMA.CMD EQU 014h DAC82DMA_CMD EQU 016h DAC82DMAR_CMD EQU 017h DACAUTSTRT_CMD EQU Olch DAC82AUTO_CMD EQU Olfh ADCIO_CMD EQU 020h ADCDMA_CMD EQU 024h ADCAUTSTRT_CMD EQU 02Ch SETTC_CMD EQU 040h AUTOBLK_CMD EQU 048h DAC84DMA_CMD EQU O74h DAC84DMAR_CMD EQU 075h DAC83DMA_CMD EQU 076h DAC83DMAR_CMD EQU 077h DAC84AUTO_CMD EQU 07dh DAC83AUTO_CMD EQU 07fh SILENCE_CMD EQU 080h HALT_CMD EQU Od0h SPKRON_CMD EQU 0d1h SPKROFF_CMD EQU 0d3h RESUME_CMD EQU 0d4h GETSPKR_CMD EQU 0d8h AUTOSTOP_CMD EQU Odah INvaYTE.cMD EQU Oeoh GETVER_CMD EQU Oelh SCRAM8LE_CMD EQU Oe2h SETTAG_CMD EQU Oe4h GETTAG_CMD EQU Oe8h ITEST_CMD EQU ofzh ; bit numbers for vF1ags vars RESET_SBFLAG EQU 0 CODECON_SBFLAG EQU 1 DPEND_SBFLAG EQU 2 ITEST_S8FLAG EQU 3 DACIO_SBFLAG EQU 4 ADCIO_SBFLAG EQU 5 T1PEND_FMFLAG EQU O T2PEND_FMFLAG EQU 1 FMIRQ_FMFLAG EQU 2 UART_FLAG EQU 0 MDATA_FLAG EQU 1 DPEND_FLAG EQU 2 FMDET_FLAG EQU 3 ; write-Back status bits in Gate Array SB_TXRDY EQU Dlh SB_RXRDY EQU 02h MPU_TXRDY EQU 04h MPU_RXRDY EQU 08h FM_TIMERZ EQU 20h FM_TIMER1 EQU 40h FM_IRQ EQU 80h ; some fm stuff T1_TRIG EQU 01h SUBSTITUTE SHEET (RULE 26) PCT/US97/15813 ?W0 98/1 1489 T2_TRIG T2_MASK T1_MASK T_RESET T2_IRQ T1_IRQ FM_IRQ CA 02265567 1999-03-10 PCT/US97/ 15813 -24- sou 02h sou 20h sou 40h sou 80h EQU 20h EQU 40h EQU 80h IF w1N_cooE VxD_LOCKED_CODE_SEG PUBLIC _NmiIsr _NmiIsr LABEL NEAR ELSE _TEXT SEGMENT ; NMI entry point here - jump over the hardware config and stub data jmp Nmiservice ALIGN 4 ; IRQ entry point here - skip to its service jmp Irqservice ALIGN 4 ; Int 67h entry point here - skip to its service jmp Int67service ALIGN 4 ; VCPI entry point here - skip to its service jmp vcpiservice ; VCPI and hardware config data here ... a11 other data at end ALIGN 4 vivocentries DD 6 DUPC?) vcpicentries DD 6 DUP(?) sharedDataP DD ? Midivectoff DD ? v86Gpmi LABEL QWORD vcoffset DD ? Vssegment DD 7 V86F1x LABEL QWORD vFoffset DD ? vFse ment DD ? Int6 Link DF ? vcpiEntry LABEL FWORD veoffset DD ? vEse1ector Dw ? Hwconfig HWSTRUCT < O, 330h, S34h, 2180h. S, 9. 1 > PUBLIC ExtMidi ExtMidi DB Ooh PUBLIC _5ynthvo1L _Synthvo1L DB 7fh PUBLIC _synthvo1R _Synthvo1R DB 7fh ENDIF ; the NMI ISR front-end/back-end code ... Nmiservice: push ecx ; —--ecx—-- mov ecx,cs add ecx,08h push ds ; ———ds--— mov ds.ecx IFE WIN_CODE mov ssoffset.esp ; switch to 1oca1 stack mov ssse1ector,ss mov esp.oFFsET stackTop mov ss,ecx ENDIF push es ;---es-—- mov es,ecx push esi :---esi--— SUBSTITUTE SHEET (RULE 26) ?W0 98/1 1489 nmisb: nmiad: nmimp: nmicd: reack: nmiex: mov push push c1d push mov add in mov inc in FOP yest push end J2 9mP DOD push and 9mP and push mov sub cmp POP 9°” JWP POP mov and ca11 JMD POP mov and ca11 JMP POP ca11 JMP DOD ca11 JMP nop mov add in in and out and out POP POP CA 02265567 1999-03-10 PCT/US97/15813 -25- esi,gpSSI ; setup Hw config ptr edx ;-——edx--— eax ;-——eax--- edx dx,[esi.ssi_wIoAddressGAJ d1,NMISTAT_0FF a1,dx ah,a1 d1 a1.dx edx ah.80h SHORT nmiex eax ah.30h SHORT nmisb ah,30h SHORT nmiad eax ; ah:a1 is NMISTAT:NMIDATA edx d1,0feh dx,[esi.ssi_wIoAddressGA] SHORT nmimp d1,0f8h eax ax.[esi.ssi_wIoAddressCOOEC] a1,4 dx,ax eax SHORT nmicd edx SHORT nmiex eax d1,ah '” edx.00O0000fh Sb1Tab1e[4*edx] ; SHORT reack ca11 the SOundB1aster service eax d1.ah edx.00000O03h Ad1Tab1e[4*edx] ; SHORT nm1ex ca11 the AdLib service edx edx,00O0OO01h MpuTab1e[4*edx] ; SHORT nm1ex ca11 the MPU-401 service edx edx,00000007h CdTab1e[4*edx] ; SHORT reack ca11 the cooec service dx,[esi.ssi_wIOAddressGA] d1,NMIsTAT_OFF ; a1.dx a1,61h ; a1,0fh a1,08h 61h,a1 a1,07h 61h.a1 eax edx ack again in case we touched CoDec re—arm NMI edge detection SUBSTITUTE SHEET (RULE 26) ?CA 02265567 1999-03-10 W0 98/11489 . -26- pop esw pop es IFE WIN_CODE 1ss esp.Spsave ENDIF pop ds pop ecx iretd IFE WIN_CODE ALIGN 4 Irqservice: push ecx mov ecx.cs add ecx,08h push ds mov ds.ecx mov ssoffset,esp mov ssse1ector,ss mov esp,0FFSET stackTop mov ss,ecx push es mov es,ecx push esi mov esi,gpSSI push edx push eax cld ca11 IrqProcess pop eax pop ed; pop es1 op es ss esp.spsave pop ds pop ecx iretd IrqProcess PROC mov add in add in test jnz and cmp jne ;a11 Jmp cmp jne ga11 JMP mov C."'P Jb out ipnos1: out ret iptsbt: ipeoi: IrqProcess ENDP dx,[§:i.ssi_wIOAddressOTTO] a1,dx d1.3 a1,dx a1,80h SHORT ipeoi a1,1fh a1,1fh_ SHORT 1ptsbt ottoTimer SHORT Irqprocess a1,1eh SHORT IrqProcess ottosbint SHORT Irqprocess a1,20h [esi.ssi_bIRQGA],8 SHORT ipnos1 0a0h.a1 20h,a1 SUBSTITUTE SHEET (RULE 26) PCT/US97/15813 ?W0 98/1 1489 vcpiservice: csok: c1s1p: c1f1p: c1r1p: 9”” Je push mov add push mov pushfd c1i mov mov mov mov push add mov push push sidt mov add mov sh? mov mov mov mov add mov mov mov mov out xor out mov mov mov cmp jae mov add IIIOV sgdt mov add sub mov mov mov 1oop mov mov 1oop I ca11 mov mov mov 1oop POP POP POP CA -27- a1,0ch ; vsgv86 ecx ; ecx.cs ecx,O8h ds ds,ecx sSofFset.esp ; SSse1ector,ss esp,0FFsET stackTop ss,ecx es ; ecx,08h es,ecx ebx esi C1ientTab ; esi,CT1addr esi,10h ebx.cs ebx.l6 ecx,O0008e00h es:[esi].ebx es:[esi+4],ecx , 4h esi,Midivectoff es:[esi].ebx es:[esi+4],ecx c1.a1 a1,80h 70h.a1 a1,a1 70h.a1 a1,c1 ecx,00O8h "” ; ebx,cs ebx.0020h SHORT csok ecx.cs ecx.0018h vEse1ector.cx ; C1ientTab esi,cT1addr ; esi,ecx esi,4 ecx,6 ebx,es:[esi+4*ecx] ; SaveGentries-4[4*ecx].ebx c1s1p ecx,6 ebx,vcpiGentries-4[4*ecx] es:[esi+4*ecx],ebx c1f1p vcpiEntry ; ecx.6 ebx,saveGentries-4[4*ecx] es:%esi+4*ecx],ebx c1r p esi ebx es 02265567 1999-03-l0 PCT/US97/1581 3 hand1e goto v86 mode separate1y save minimum regs no ints! switch to 1oca1 stack setup g1oba1 data se1ector patch c1ient IDT find a GDT patch entry note GDT entry for ca11 point into ciient tab1e save current c1ient entries ; copy-in the rea1 VCPI GDT entries make the rea1 VCPI ca11 : restore c1ient GDT entries restore working regs restore g1oba1 se1ector SUBSTITUTE SHEET (RULE 26) ?W0 98/1 1489 15s popfd POP POD retf vsgv86: mov mov mov add mov add mov mov mov sidt mov add mov sh1 mov mov mov mov add mov mov mov out xor out IIIOV IIIOV HIOV IIIOV mov mov mov IIIOV ITIOV mov sgdt mov add sub mov c1fix1p: mov mov 1oop mov I mov mov mov mov mov mov nov JMP Int67service: cmp jne push mov push add CA 02265567 1999-03-10 -28- esp.SpSave ; ds ecx ; eax,ds ; gs,eax eax,cs ; eax.08h ds.eax eax.08h es.eax EesP].ebx esp+4],ecx C1ientTab ; ebx,CT1addr ebx.10h eax,cs eax.16 ecx,00O08e0Oh es:[ebx],eax es:[ebx+4].ecx a1,04h ebx,Midivectoff es:[ebx],eax es:[ebx+4],ecx a1,80h 70h.a1 a1.a1 70h,a1 eax.[esp+10] ; ax.[esp+8] ebx,sharedDataP es:[ebx+4],eax eax,vFoffset ' ; [esp+8],eax eax,vFsegment [esp+12],eax eax.cs vEse1ector,ax ; C1ientTab ebx,cT1addr ; ebx.eax ebx.4 ecx,6 eax,vcpiGentries-4[4*ecx] es:[ebx+4*ecx],eax c1fix1p CT1addr,ebx ; ea§,cr3 ; C11entCr3.eax ecx.[esp+4] ebx.[esp] eax.gs ds,eax eax,0de0ch ; cs:vcpiEntry ax,Ode01h ; SHORT i67tfix eax eax,cs edx eax.10h PCT/US97/15813 restore stack restore regs save regs setup seg registers patch the c1ient IDT save c1ient V86 destination setup our v86 destination note se1ector for far ca11 point to c1ient GDT patch entry ; copy-in the rea1 VCPI GOT entries save GDT entry Iaddr for fixup save c1ient's cr3 re—init function arg VCPI GetPMI C311? SUBSTITUTE SHEET (RULE 26) ?W0 98/ l 1489 i67s32: 167tfix: i67fx1p: i67tpic: i67pset: push mov mov Tar ht JC and mov mov mov sh1 mov mov mov mov mov mov POP POP P°P Jmp cmp jne push push mov add mov add mov mov mov mov mov l'llOV I1IOV MOV mov 1oop IIIOV mov POP POD iretd cmp jne push mov push add mov mov mov 9”” mov sub add xor mov sh1 sub mov CA 02265567 1999-03 -29- ds ds,eax eax,ss eax.eax eax,22 SHORT i67s32 esp,000Offffh edx,cs:SharedDataP ; [edx+8].di ; ax.[esp+16] : eax,16 ax.[esp+12] [edx],eax eax,cs:vGoffset ; [esp+12].eax eax,cs:vGsegment £esp+16J.eax s edx eax _ cs:Int67L1nk ; ax,0dee0h SHORT i67tpic ebx ; ecx eax.cs eax.08h ds.eax eax.08h es,eax eax,cr3 RegSave.eax eax.c1ientCr3 ; cr3.eax ; ebx,CT1addr ecx,6 eax.vivoGentries—4[4*ecx] es: ebx+4*ecx],eax 167 x1p eax,Regsave cr3,eax ecx ebx ax.0de0bh SHORT i67tcmd edx edx.cs ds edx.08h ds.edx edx,gpSSI a1.b1 [edx.ssi_bIRQGA].08h SHORT i67pset a1.c1 a1,08h a1,[edx.ssi_bIRQGA] edx,edx d1.a1 edx.3 edx.10h Midivectoff.edx -10 PC17US97?5813 setup_ds:[edx] for shared data save 1n1t di to shared space save v86 return to shared space force v86 ret to vivo gpmi code 1ink to norma1 PM hand1er save regs need c1ient's age context don't use stac unti1 restored ; restore c1ient GDT entries SUBSTITUTE SHEET (RULE 26) ?W0 98/1 1489 i67tcmd: i67vcmd: i67upd: i67ssv: i67gsv: i67smt: i67gmt: i67sxm: i67gxm: mov pop POP Jmp 9”” JMP push mov add mov mov mov mov mov mov push push push IIIOV c1d cmp jne ;a11 JMP ?mP jne push ca11 add mov mov ga11 Jmp cmp jne and mov mov Jmp cmp jne mov JMD cmp jne and push ca11 qdd JMP cmp jne hov Jm? cmp jne and mov Jmp cmp jne CA 02265567 1999-03-10 -30- a1,0bh ds edx cs:Int67Link ax,0dee1h SHORT i67vcmd cs:Int67Link ecx ecx,cs ecx.08h ds,ecx SSoffset.esp sSse1ector,ss esp.OFFSET StackTop ss,ecx es,ecx esi edx eax esi.gpSSI bh.00h SHORT i67upd Irqprocess i67cmdex bh,01h SHORT i67ssv [esi.ss1_wHardwareoptions] _otto_init esp.4 SystemTime,O Activecount.0 _synth_init i67cmdex bh,02h SHORT i67gsv , fh _synthvo1L.b1 _SynthVo1R,b1 SHORT 167cmdex bh,O3h SHORT i67smt b1,_Synthvo1L SHORT i67cmdex - bh,O4h SHORT i67gmt fh ebx _synth_set_MT32 esp,4 SHORT i67cmdex bh.05h SHORT i67sxm b1._MT32 SHORT i67cmdex bh,06h SHORT i67gxm fh ExtMidi.b1 SHORT 167cmdex bh,07h SHORT i67sws SUBSTITUTE SHEET (RULE 26) PCT/US97/15813 ? W0 98/11489 mov _ Jmp 167sws: cmp jne and mov _ JNP 167gws: cmp jne mov JMD i67gbt: cmp 'ne sf mov _ JMP 167pdt: cmp jne hot JWP nop i67cmdex: POP P09 0P ss 9°” wretd ENDIF CA 02265567 1999-03-10 -31- b1,ExtMidi SHORT i67cmdex bh.O8h SHORT i67gws ,7fh wssswtch.b1 SHORT i67cmdex bh.09h SHORT i67gbt b1,wssswtch SHORT i67cmdex bh,0ah SHORT i67pdt g¥.[esi.ssi_wHardwareOptions] .a SHORT i67cmdex bh.Obh SHORT i67cmdex SHORT i67cmdex eax edx esi esp,spsave ecx PCT/US97/15813 ; hand1e otto timer int - assumes 1oca1 stack. se1s set. esi->Hw; ottoTimer PROC push push push 9'“? 3e dec jnz c1c ca11 otupd: push mov add movh pus ca11 add P09 POP POP ret ottoTimer ENDP eax ecx edx Activecount,0 SHORT otupd Activecount SHORT otupd TimerCt1 1000 eax.SystemTime eax,16 systemTime.eax eax _synth_update esp,8 edx ecx eax ; hand1e otto 58 int - assumes 1oca1 stack. se1s set, esi->Hw; PUBLIC ottosbint Ottosbint PROC push eax SUBSTITUTE SHEET (RULE 26) ?W0 98/1 1489 push push push ca11 add xor push push ca11 add push ca11 add pushd push ca11 add xor push push ca11 add pushd push ca11 add bts mov add in push and out push mov sub mov out POP POP out push ca11 add POP POP POP ret ottosbint ENDP CA 02265567 1999-03-10 PCT/US97/15813 -32- ecx edx leh ; _otto_io_page esp,4 freq page eax,eax ; eax 04h _otto_io_write esp,8 3eh . ; _otto_1o_page esp,4 8000000Oh ; 08h _otto-1o_write esp,8 zero freq addr page open 1oop eax,eax ; eax Och _otto_io_jam esp.8 0ff04h 00h _otto_1o_jam esp.8 ZBFO accum id1e mode sbF1ags,ITEsT_SBFLAG ; forced-int dx,[esi.ssi_wIoAddressGA] d1,NMICTL.OFF ; a1,dx eax a1.0cDh dx,a1 edx ; force int dx.[esi.ssi_wIoAddressCoDEC] dx.4 a1.40h dx.a1 edx eax dx.a1 38h _otto_io_read esp,4 note ki11 coDec virtua1ization ; re-enab1e Cooec v1rtua11zation edx ecx eax PUBLIC TimerCt1 TimerCt1 PRQC push push push pushfd push ch11 add popfd eax ecx edx lfh _otto_io_page esp,4 SUBSTITUTE SHEET (RULE 26) ?W0 98/1 1489 jnc push Jmp push tcoff: tcset: push ca11 add POP POD POP f'Et T1merct1 ENDP CA 02265567 1999-03-10 -33- SHORT tcoff 0ff28h SHORT tcset 0ff08h O _otto_io_jam esp,8 edx ecx eax IFDEF DOS_DEBUG Dbstatus PROC push push push mov add mov mov mov mov inc cmp jbe mov dsl: mov POP POP POD ret Dbstatus ENDP eax ebx es eax.cs eax.10h es,eax ebx,000b8OD0h + 2*(80*24 + 79) a1,Debu Byte es:[ebxa.a1 a1 a1,'9' SHORT dsl a1,'0' Debug8yte,a1 es ebx eax PUBLIC DbPUt8 DbPut8 PROC push push push push HIOV add mov mov xor mov d81: ro1 mov and cmp jae qdd Jmp add d82: d83: mov ebx ecx edx es ecx.cs ecx,10h es.ecx ebx.DebugPtr ecx.ecx c1,2 d1,‘ SHORT d83 d1.'A' — Oah es:[ebx].d1 SUBSTITUTE SHEET (RULE 26) PCT/US97/15813 ?W0 98/11489 d8nw1: d8nw2: DbPut8 DbPut16 d161: d162: d163: d16nw1: d16nw2: inc 1nc cmp mov Toop mov inc inc C.'“P Jb mov MOV mov POP POP POP POP ret ENDP CA 02265567 1999-03-10 -34- ebx ebx ebx,0bO000h+3840 d8nw1 ebx,0b00O0h SHORT d8l BYTE PTR es:[ebx],' ' ebx ebx ebx.0b00O0h+384O d8nw2 ebx,0b0000h BYTE PTR es:[ebx],'*' DebugPtr,ebx es edx ecx ebx PUBLIC DbPut16 PROC push push push push mov add mov mov X0!‘ IIIOV ro1 mov and ‘.3"'P Jae gdd Jmp add mov jnc 1nc '§"'P Jb mov Toop mov ync 1nc C.'"P mov IIIOV [HOV POP POP ebx ecx edx es ecx.cs ecx.10h es,ecx ebx.DebugPtr ecx,ecx c1.4 ax,4 d1,a1 d1,0fh d1,0ah d162 d1,'0' SHORT d163 d1,'A' - Oah es:[ebx],d1 ebx ebx ebx,0bO00Oh+3840 d16nw1 ebx,0b000Oh d161 BYTE PTR es:[ebx],' ' ebx ebx ebx,0bO000h+3840 d16nw2 ebx,0b0000h BYTE PTR es:[ebx],'*' DebugPtr.ebx es edx SUBSTITUTE SHEET (RULE 26) PCT/US97/15813 ?CA 02265567 1999-03-10 W0 98/11489 - PCT/US97/15813 V -35- pop ecx pop ebx ret DbPutl5 ENDP PUBLIC DbPut32 DbPut32 PROC push ebx push ecx push edx push es mov ecx.cs add ecx,10h mov es.ecx mov ebx,DebugPtr xor ecx,ecx mov c1.8 d321: ro1 eax,4 mov d1.a1 and d1,0fh cmp d1,0ah jae d322 add d1.'0' jmp SHORT d323 d322: add d1,‘A‘ — Oah d323: mov es:[ebx].d1 inc ebx inc ebx cmp ebx,0b00O0h+384O jb d32nw1 mov ebx.0b000Oh d32nw1: 1oop d321 mov BYTE PTR es:[ebx],' ' inc ebx inc ebx cmp ebx.0b000Oh+384O jb d32nw2 mov ebx,0b0O00h d32nw2: mov BYTE PTR es:[ebx],'*' mov DebugPtr,ebx pop es pop edx pop ecx pop ebx ret DbPut32 ENDP ENDIF cdkead PROC push edx push eax mov dx,[esi.ssi_wIoAddressCoDEC] in a1.dx and a1.0e0h or a1.ah out dx,a1 pop eax inc d1 SUBS?TUTESHEET(RULE26) ?W0 98/1 1489 cdnead Cdwrite Cdwrite CdCtr1 Cdctr1 Setnate S PHEWI tcok: in POD ret ENDP PROC push push mov in and or out l?°P 1nc out DOD ret ENDP PROC push xchg mov out gchg 1nc out POP ret ENDP CA 02265567 1999-03-10 PCT/US97/15813 a'| ,dx '36“ edx edx eax ‘ _ dx.[es1.ss1_wIoAddressCODEC] edx ah.a1 dx,[esi.ssi_wIoAddresscoDEC] dx,a1 ah,a1 d1 dx.a1 edx ; a function to set the cooec freq corresponding to a $8 Tconst PROC 9”” 3ne ret push push push mov 9"‘? ]be mov xor mov not inc mov xor d1v mov mov l'|'|OV mov ca11 mov 1nc ca11 a1,Tconst SHORT srnew eax ecx edx TConst.a1 a1.0f0h tcok a1,0fOh ecx,ecx c1,a1 c1 ecx eax.100000o edx,edx ecx sbsrate.ax d1,a1 a1,ah ah,CD_UFREQ Cdwrite a1,d1 ah _ Cdwr1te SUBSTITUTE SHEET (RULE 26) ? CA 02265567 1999-03-10 W0 98/11489 -37- pop edx pop ecx pop eax ret SetRate ENDP ; a function to mute/unmute the AD-1848 DAC MuteCt1 PROC push eax push ecx ff JC muteon muteo : mov sqkr?tat,0ffh xor c ,c jmp SHORT setvo1 muteon: mov S?krStat,0Oh mov c .80h setvo1: h mov a .CD_DACLVOL ca11 CdRead and a},O{fh or a ,c ca11 Cdwrite mov ah.CD_DACRvOL ca11 cdwrite pop ecx pop eax ret MUteCt1 ENDP ALIGN 4 PUBLIC Iompuoata IoMpuData PROC test ah,40h ’nz SHORT mdout tr vF1ags.DPEND_FLAG jc SHORT mdmore ca11 GetMscStat Or a1,MPU,RXRDY ca11 SetMscStat ret mdmore: mov a1.MpuData ca11 MpuPutData ret mdout: bt vF1ags.MOATA_FLAG jc SHORT domidi ret domidi: test ExtMidi,7fh jnz mduart ; apw make short test a1,80h jnz SHORT status mov d1,MidiStat cmp d1.0fOh jae mpdone xor edx,edx mov d1.Mid1Curc mov MidiData[edx],a1 cmp d1,MidiDatC jb SHORT cdmore mov MidiCurc.0 ; At this point we have accumu1ated a fu11 MIDI message SUBSTITUTE SHEET (RULE 26) PCT/US97/15813 -on ?CA 02265567 1999-03-10 wo 93/11439 PCT/US97/15813 -38- ; put it in eax and pass it to the synth. The format wi11 be ; EAX: D31-D24 D23-D16 O15—D8 D7-D0 ; MIDI: ZERO DATA1 DATAO STATUS cmp Activecount,0 ; make sure timer is on mov Activecount,20O jne SHORT midca11 stc ca11 TimerCt1 midca11: mov eax,MidiMessage IF WIN_CODE Trace_out "IoMpuData: MIDI Message Dump : #EAx”, Deb1eve1Max ENDIF push eax ca1T _synth_process_MIDI add esp.4 jmp SHORT mpdone cdmore: inc d1 mov MidicurC,d1 jmp SHORT mpdone status: cmp a1,0f0h jae SHORT sysstat mov Midistat,a1 mov Mid1curC,0 cmp a1.0c0h jae sttex mov Mid1DatC.1 jmp SHORT mpdone sttex: cmp a1,0e0h jb stodat mov M1diDatC,1 jmp SHORT mpdone stodatz mov MidiOatC,O jmp SHORT mpdone sysstat: cmp a1,0f8h jae SHORT mpdone mov MidiStat,a1 mpdone: ret mduart: mov ah,a1 mov ecx.40000Oh mov dx,[esi.ss1_wIoAddressGA] add edx,UARTSTAT_OFF mduwtx: in a1,dx test a1,02h jz SHORT mduwtx mov a1.ah inc edx out dx,a1 ret IoMpuData ENDP ALiGN 4 PUBLIC IoMpuCstat IoMpuCstat PROC test ah,40h jnz SHORT mcout ret mcout: cmp a1,0ffh SUBSTITUTE SHEET (RULE 26) ?. ..m...W...........\......w.... .,4 ............u.u..»......¢..._.~ W, W0 98/ 1 1489 'ne tr ptr JC mov ca11 mcnak: push ca11 add mov c1c ca11 ret mcnores: ht Jnc ret ; 1nte11igent—mode commands hand1ed here ... mpuint: mov mov ca11 cmp 'ne ts dodx: bts pushd ca11 add mov mov stc ca11 ret mitv: cmp jne mov bts ret mitr: 9mP Jne mov bts ret mitdx: and 9N9 Je ret IOMpUCStat ENDP GetMscStat PROC push mov add in POD ret Getmscstat ENDP SetMSCStat PROC CA 02265567 1999-03-10 -39- SHORT mcnores vF1ags,MDATA_FLAG vF1ags.UART_FLAG SHORT mcnak a1.0feh MpuPutData Offffffffh _synth_a11_notes-off esp,4 Act1veCount,0 T1merct1 vF1ags,UABT_FLAG SHORT mpu1nt ah,a1 a1.0feh MpuPutData ah,03fh SHORT mitv vF1ags,UART_FLAG vF1a s,MDATA_FLAG Offf ffffh _synth_a11_notes_off esp,4 _num_active_voices.24 ActiveCount,200 TimerCt1 ah.0ach SHORT mitr MpuData,15h vF1ags,DPEND_FLAG ah,0adh SHORT mitdx MpuData,01h vF1ags,DPENo_FLAG ah,0f0h ah,0d0h SHORT dodx edx dx,[esi.ssi_wIoAddressGA] d1,MSCWBAK_0FF a1,dx edx SUBSTITUTE SHEET (RULE 25) PCT/US97/15813 ?W0 98/1 1489 push mov add out POP ret SetMSCStat ENDP Sb1PutData PROC push mov add out 909 push ca11 or ca11 POP ret Sb1PutData ENDP MpuPutData PROC push mov add out POD push ca11 and ca11 POD ret MpuPutData ENDP ALIGN 4 CA 02265567 1999-03-10 edx -40- dx,[esi.ssi_wIoAddressGA] d1,MSCWBAK_0FF dx,a1 edx edx dx.[esi.ssi_wIoAddressGA] d1,SBWBAK_OFF dx.a1 edx eax GetMscStat a1,SB_RXRDY SetMscSTat eax edx dx,[esi.ssi_wIoAddressGA3 d1.MPuwBAK_0FF dx,a1 edx eax GetMscStat a1,NOT MPU_RXRDY SetMscSTat eax PUBLIC IoSb1Reset IoSb1Reset PROC test jnz ret srout: pest J2 ret sbresoz mov ca11 mov ca11 mov ca11 mov xor out sub out IIIOV IIIOV MOV IIIOV l'|10V ah.40h SHORT srout a1,01h SHORT sbreso ax.((CD_CONFIG on 40h) SHL 8) on 04h CdCtr1 ax,(CD_PFORM SHL 8) on Ooh Cdctrl ah,CD_CFORM cdCtr1 dx.[esi.ssi_wIoAddresscoDEc] a1.a1 dx.a1 d1.4 dx,a1 CmdProc,oFFsET Parsecmd SbAccum,0aah SbxorPat,96h Tconst.0ffh sbF1ags.0 SUBSTITUTE SHEET (RULE 26) PCT/US97/15813 ?W0 98/ l 1489 stc ca11 ca11 mov ca11 mov ca11 ret Iosb1Reset ENDP HwC1eanup PROC push push mov sub X0!‘ out mov add in and out mov ca11 mov ca11 gest J2 in or inc in out drqok: mov add in out dec out mov add in POD POP ret HwC1eanup ENDP ALIGN 4 CA 02265567 1999-03-10 ’ PCT/US97/15813 -41- MuteCt1 HwC1eanup ax.(CD_PINCTL SHL 8) OR Oc2h Cdwrite a1.0aah sb1PutData eax edx g¥,gesi.ssi_wIOAddressCoDEC] a1:a1 dx.a1 dx.[es1.ssi_wIOAddressGA] d1,CONTROL_0FF a1,dx a1.0f8h dx,a1 ax,(§D_CONFIG SHL 8) OR 00h Cdwr1te ah,CD_TINIT cdRead a1.10h SHORT drqok a1,dx a1.04h d1 a1,dx dx.a1 gx,[esi.ssi_wIOAddressGA] a1:dx dx.a1 d1 dx,a1 gx,[esi.ssi_wIOAddressCODEC] I a1,dx edx eax PUBLIC Iosb1Data Iosb1Data PROC test ‘nz _tr JC ca11 and ca11 ret ah,40h SHORT sdout sbF1ags,DPEND_sBFLAG SHORT dpend Getmscstat a1,NOT SB_RXRDY setmscstat : data write? ; got a pending byte? SUBSTITUTE SHEET (RULE 26) ?W0 98/1 1489 dpend: sdout: Iosbloata ENDP IoSb1Cstat PROC txnorm: SCOUtZ Parsecmd LABEL NEAR : dacdma: DCSEITCI pcDacIo: dioset: pcAdcIo: xor ca11 ret ret ALIGN 4 CA 02265567 1999-03-10 PCT/US97/15813 -42- a1,a1 Sb1PutData PUBLIC Iosb1cstat test Jnz ca11 bt jnc inc test JZ or ca11 ret and ca11 ret imp cmp jne mov PEI 9”” jne mov ret cmp 'ne _ts JC mov ca11 mov xor out mov ca11 mov ca11 inc ca11 IIIOV MOV ret 9”? ne _ts JC MOV ah,40h SHORT scout GetMscStat sbF1ags,CODECON_SBFLAG SHORT txnorm Togg1e Togg1e,04h SHORT txnorm a1,S8_TXRDY Setmscstat ; if the DAC is on, we need to togg1e ; pass norma1 Txkdy a1,NOT SB_TXRDY $etMscStat [cmdProc] : go to current command process parse for a new command a1,DACDMA_CMD SHORT pcSetTc [CmdProc],oFFSET GetDacc1 a1.SETTC_CMD SHORT pCDaCIO [cmdProc],oFFsET GetTc a1,DACIO_CMD SHORT pcAdcIo sbF1ags,DAcI0_SBFLAG dioset b ax.C(CD_CONFIG on 40h) SHL 8) on 45h CdCtr1 dx.[esi.ssi_wIoAddressCoDEC] a1.a1 dx.a1 ax,(CD_PINCTL SHL 8) OR 0c0h Cdwrite ax,(CD_UFREQ SHL 8) OR 0c3h cdwrite ah Cdwrite Tconst.0ffh [CmdProc],0FFSET GetDacIo a1.nAcIo_cMo SHORT pcDacAon sbF1ags,AoCIO_SBFLAG aioset ax.((Co_coNFIG on 40h) SHL 8) on 86h SUBSTITUTE SHEET (RULE 26) ?W0 98/1 1489 ca11 mov XDI” out mov ca11 mov ca11 inc ca11 mov aioset: mov add in ca11 ret pcDacAon: cmp jne dacauto: mov mov ca11 dec mov ca11 mov ca11 bts ret pcAdcAon: Qmp Jne adcauto: mov mov ca11 dec mov ca11 mov ca11 bts ret pcAutooff: cmp jne push push mov in or out POD DOD ret pcAutoB1k: cmp jne mov ret pcHa1t: cmp 'ne tr jnc push CA 02265567 1999-03-10 PCT/US97/15813 CdCtr1 43 dx.[esi.ssi_wIoAddressCoDEC] a1,a1 dx.a1 ax,(CD_PINCTL SHL 8) OR OcOh Cdwrite ax,(CD_UFREQ SHL 8) OR 0c3h Cdwrite ah Cdwrite Tconst,0ffh d¥,[esi.ssi_wIoAddressCoDEc] a1Idx sb1PutData a1,DACAUTSTRT_CMD SHORT pcAdcAon ah.CD_PCOUNTL a1.Auto31kL Cgwrite a a1,Auto81kU cdwrite ax.((cD_coNFIG on ooh) SHL 8) on 01h CdCtr1 sbF1ags.CODECON_SBFLAG aT,ADCAUTSTRT_CMD SHORT pcAutooff ah.CD_CCOUNTL a1,Auto81kL cdwrite ah a1,AutoB1kU Cdwrite ax,((CD_CoNFIG OR 00h) SHL 8) OR 02h CdCtr1 sbF1ags.CoDECoN_SBFLAG a1.AuTosToP_cMD SHORT pcAutoB1k eax edx dx,[esi.ss1_wIoAddressc0DEC] a1,dx a1,20h dx,a1 edx eax a1.AUTOBLK_CMD SHORT pcHa1t [cmdProc],oFFSET GetAbL a1,HALT_CMD pcResum sbF1ags,CODECON_SBFLAG ha1ted eax SUBSTITUTE SHEET (RULE 25) ?W0 98/1 1489 ha1ted: pcResum: resumed: push mov ca11 mov add out DOD DOD ret cmp 'ne _ts JC push mov ca11 POD ret pcAdcDma: pcItest: cmp jne mov ret cmp 'ne ts push push mov sub mov out POP POD ret pcsi1ence: 9”” jne mov ret pcspkron: cmp jne c1c ca11 ret pcspkroff: cmp jne stc ca11 ret pcGetSpkr:- PCSCPZMZ GNP Jne mov ca11 ret cnip jne CA 02265567 1999-03-10 edx -44- ax,(CD_CONFIG SHL 8) OR 00h Cdwrite d§,[esi.ssi_wIOAddressCoDEC] dx,a1 edx eax a1.RESUME_CMD SHORT pcAdcDma sbF1ags,CoDECoN_SBFLAG resumed eax ax,(CD_CONFIG SHL 8) OR 01h Cdwrite eax a1,AocoMA_cMo SHORT pcItest [CmdProc],OFFSET GetAdcc1 a1,ITEST_CMD SHORT pcsi1ence sbF1ags,ITEsT_sBFLAG eax edx dx,[esi.ssi_wIoAddressCoDEC] dx,4 a1,40h dx.a1 edx eax a1,SILENCE_CMD pcspkron _ CmdProc,Gets11C1 a1,SPKRON_CMD SHORT pcspkroff MuteCt1 a1,sPKRoFF_cMD SHORT pccetspkr Mutect1 a1.GETSPKR_CMD SHORT pcscram a1.SpkrStat Sb1PutData a1.SCRAMaLE_CMD SHORT pcGetver SUBSTITUTE SHEET (RULE 26) PCT/US97/15813 ?W0 98/1 1489 MOV ret pcGetver: cmp jne mov ca11 bts ret pcxnvaytez 9mP Jne mov ret pcsetTag: Smp Jne mov ret pcGetTag: cmp jne mov ca11 ret pccmps: cmp jne JMD 9”” lne Jmp cmp jne Jmp Smp Jne Jmp cmp ‘ne JMP 9”” Jne pccsgo: stc ca11 imp pccsl: pcCs2: pcCs3: pcCS4: pcCSS: pccmpA: cmp jne JMP Fmp qne JWP cmp jne pcCAgo: stc ca11 imp pcCA1: pcCA2: CA 02265567 1999-03-10 -45- [CmdProc],oFFsET Getscram a1,GETvER.CMD SHORT pcInvByte a1,02h sb1PutData sbF1ags.DPEND_sBFLAG a1,INVBYTE_CMD SHORT pcSetTag cmdProc,oFFsET Getlnv a1,SETTAG_CMD SHORT pcGetTag CmdProc,0FF5ET GetTag a1,GETTAG_cMD SHORT pccmps a1,TagByte sb1Putoata a1,oAc84oMA_cMo SHORT pcCS1 SHORT pccsgo a1,DAC84DMAR_CMD SHORT pCCS2 SHORT DCCSQO a1.DAC83DMA_CMD”’ SHORT pcCS3 SHORT pccsgo a1.oAc83oMAR_cMn SHORT pcCS4 SHORT pccsgo a1,oAc82oMAR_cMo SHORT pcCS5 SHORT pccsgo a1.oAc82nMAR_cMo SHORT pccmpA MuteCt1 dacdma a1.DAC84AUTO_CMD SHORT pcCA1 SHORT pcCAgo a1,oAc83AuTo-cMD SHORT pCCA2 SHORT pcCAgo a1,DAc82AuTo_cMo SHORT pcNone MuteCt1 dacauto SUBSTITUTE SHEET (RULE 26) PCT/US97/15813 ?CA 02265567 1999-03-10 W0 98/11489 PCT/US97/15813 -46- PcNone: ret GetAdcC1: mov ah,CD_CCOUNTL ca11 cdwrite mov [CmdProc],OFFSET GetAdcCu ret GetAdccu: ; this process starts the ADC mov ah,CD_CCOUNTu ca11 cdwrite bts sbF1ags,CODECoN_sBFLAG jc adcson mov ax.((CD_CONFIG OR 20h) SHL 8) OR 02h ca11 cdctr1 adcson: mov CmdProc.oFFsET Parsecmd ret GetDacIo: push edx mov dx,[esi.ssi_wIoAddresscoDEc] add d1.3 out dx,a1 pop edx mov CmdProc.0FFSET Parsecmd ret GetSi1c1: mov DmaCountL,a1 mov CmdProc,OFFSET GetSi1Cu ret GetSi1Cu: mov DmaCountU.a1 xor ecx,ecx Z 0 ; derive otto samp1e count mov cx,DmaCount inc ecx mov eax,31250 xor edx,edx mu1 ecx xor ecx,ecx mov cx,SbSrate xor edx.edx div ecx inc eax sh1 eax.11 : create a 1oop—end va1ue push eax push 3eh ; addr page ca11 _otto_io_page add esp,4 push 08h _ _ ; set 1oop-end (eax pre-pushed) ca11 _otto_1o_wr1te add esp,8 push leh ; freq page ca11 _otto_io_page add esp.4 pushd 0ff20h ; non-Tooping, int enab1e push 00h ca11 _otto_io_jam add esp,8 pushd 0800h ; frequency is 1 push 04h ca11 _otto_io_write add esp,8 SUBSTITUTE SHEET (RULE 26) ?W0 98/1 1489 IIIOV ret GetDacC1: mov ca11 mov ret Getoaccuz mov ca11 bts jnc I mov add in ;est )2 mov ca11 out dacst: IHOV ca11 dacex: mov ret GetAbL: mov mov ret GetAbu: mov mov ret GetTc: ca11 HIOV ret Getscram: xor add mov add out mov ror dec in or out mov ret Getlnv: not ca11 mov ret GetTag: mov mov ret IoSb1Cstat ENDP CA 02265567 1999-03-10 ~ PCT/US97/15813 -47- CmdProc.oFFSET Parsecmd ah,CD_PCOUNTL cdwrite [CmdProc].oFFsET Getoaccu ; this process starts the DAC ah,CD.PCOUNTU cdwrite sbF1ags.CODECON_sBFLAG dacst g¥,£esi.ssi_wIoAddressCODECJ a1.dx a1.01h SHORT dacex ax,(CD_CoNFIG SHL 8) OR 00h Cdwrite dx,a1 ax.((CD_CONFIG OR 20h) SHL 8) OR 01h CdCtr1 CmdProc,oFFSET Parsecmd AutoB1kL,a1 [CmdProc],oFFSET GetAbU Autoa1kU.a1 CmdProc,0FFSET Parsecmd setaate cmdProc,oFFSET Parsecmd a1,sbxorPat a1.sbAccum dx,[esi.ssi_wIoAddressGA] d1.JAMoATA_oFF dx,a1 SbAccum.a1 3?xorPat,2 a1.dx a1,02h dx.a1 cmdProc.oFFsET Parsecmd a1 sb1PutData CmdProc,OFFSET Parsecmd TagByte.a1 cmdProc.oFFSET Parsecmd SUBSTITUTE SHEET (RULE 26) ?CA 02265567 1999-03-10 W0 98/11489 PCT/US97/15813 -48- ALIGN 4 PUBLIC IoSb1Rxrdy IoSb1Rxrdy PROC test ah.40h jnz srxout mov dx,[esi.ssi_wIoAddresscoDEc] add 1.2 in a1.dx test a1,01h jz SHORT notcd sub d1,2 in a1,dx test a1.20h jz c1rint mov ax.(CD_CONFIG SHL 8) OR 00h ca11 cdwrite btr sbF1ags,CODECON_SBFLAG c1rint: mov ah,18h ca11 Cdnead or a1,80h ca11 DbPut8 add d1,2 _ out dx,aT ; c1ear coDec 1nt mov ah,18h ca11 CdRead ca11 DbQut8 Jmp SHORT rxstat notcd: btr sbF1ags,ITEsT_SBFLAG ; did we fire-off a test int? jnc rxstat sub d1.6 xor a1,a1 out dx.a1 ; ki11 forced IRQ rxstat: — ret srxout: ret Io5b'l Rxrdy ENDP ALIGN 4 PUBLIC IoFmAstat IoFmAstat PROC test ah,40h 'nz SHORT faout tr vF1ags.FMDET_FLAG jnc SHORT farex pushd Offffffffh ca11 _synth_a11_notes_off add esp,4 mov _num_active_voices.l2 farex: ret faout: . mov FmAddr.a1 ; FM address reg wr1te ret IoFmAstat ENDP ALIGN 4 PUBLIC IoFmData IoFmData PROC test ah.40h ; writing fm data port? SUBSTITUTE SHEET (RULE 26) ?CA 02265567 1999-03-10 wo 93/1 1439 PCT/US97/15813 _ -49- Jnz SHORT fdout mov a1,0ffh ret fdout: xor edx,edx ; FM data reg write mov d1,FmAddr mov _fm_array[edx],a1 ; fi11-in FM data array mov dh,d1 cmp dh,01h je SHORT fmdenq and dh,Of0h cmp dh,0b0h ; need to process FM notes? jne SHORT fmtdet fmdenq: _ _ cmp Act1vecount,0 ; make sure t1mer is on mov Act1vecount,200 jne SHORT fmca11 stc ca11 Timerct1 fmca11: push edx ca11 _fm_process add esp.4 ret fmtdet: cmp FmAddr.4 ; test for timer detection jne SHORT fmdex mov ah,a1 ca11 GetMscStat fmdtl: test ah,T1_TRIG jz SHORT fmdtz or a1.T1_IRQ OR FM_IRQ bts vF1ags,FMDET_FLAG fmdt2: test ah,T2_TRIG jz SHORT fmdml or a1,T2_IRQ OR FM_IRQ bts vF1ags,FMDET_FLA§ fmdml: test ah.T1_MAsK jz SHORT fmdmz and a1,NOT T1_IRQ fmdm2: test ah,T2_MASK j 2 SHORT fmdt r and a1,NOT T2_IRQ fmdtr: test a1.T1_IRQ OR T2_IRQ jnz SHORT fmdstat and a1.NoT FM_IRQ fmdstat: ca11 setnscstat fmdex: ret IoFmData ENDP ALIGN 4 PUBLIC IocdAddr IOCdAddr PROC test ah,40h jnz SHORT caout ret caout: mov CdAddr,a1 ret IocdAddr ENDP SUBSTITUTE SHEET (RULE 26) ?CA 02265567 l999-03- 10 W0 98/1 1489 ALIGN 4 -50- PUBLIC IoCdData Iocdoata PROC test ah,40h jnz SHORT cdout mov ah,cdAddr and ah,1fh cmp ah,CD_MISC jne SHORT cdrex mov BYTE PTR [esp+4].0ah cmp wssSwtch.0 jne SHORT cdrex mov BYTE PTR [esp+4].0ffh cdrex: ret cdout: mov ah,CdAddr and ah.1fh cmp ah,CD_PFORM jne SHORT cdtpin xor edx.edx mov d1.a1 and d1.0fh mov dx,FreqTab1e[2*edx] mov ah,CD_uFREQ mov a1.dh ca11 cdwrite inc a mov a1,d1 ca11 cdwrite ret cdtpin: cmp ah.CD_PINCTL jne SHORT cdtmsc or a1,0c0h ca11 Cdwrite ret cdtmsc: cmp ah,CD_MISC jne SHORT cdt1cc mov a1.50h ca11 Cdwrite ret cdt1cc: cmp ah.CD_CCOuNTL jne SHORT cdtucc mov ah,CD_PCOUNTL ca11 cdwrite ret ' cdtucc: cmp ah.CD_CCOUNTU jne SHORT cdwex mov ah,CD_PCOUNTU ca11 cdwrite cdwex: ret Iocdoata ENDP ALIGN 4 PUBLIC IOWSS Iowss PROC test ah,40h jnz SHORT wsout cmp wssSwtch,0 jne SHORT wiwss mov BYTE PTR [esp+4].0ffh wiwss: ret wsout: SUBSTITUTE SHEET (RULE 26) PCT/U S97/ 15813 ?CA 02265567 1999-03-10 SUBSTITUTE SHEET (RULE 26) WO 98/11489 PCT/US97/15813 -51- cmp wssSwtch,O jne SHORT wopass xor a1,a1 out dx,a1 wopass: ret Iowss ENDP ALIGN 4 PUBLIC IoPass IoPass PROC ret IoPass ENDP IF wIN_CODE VxD_LOCKED_CODE_ENDS VxD_LOCKED_DATA_SEG ENDIF ALIGN 4 IFE WIN_CODE PUBLIC gpSSI _ gpSSI DD OFFSET HwConf1g IFDEF DOS_DEBUG DebugPtr DD (0bO000h + 2*80*8) ENDIF ENDIF MpuTab1e LABEL DWORD DD IoMpuData, Ionpucstat Sb1Tab1e LABEL DWORD ~- DD IoPass. IoPass, IoPass, IoPass DD IoPass, IoPass. IoSb1Reset, IoPass DD IoFmAstat, IoFmData, IoSb1Data, IoPass DD IoSb1Cstat. IoPass, IoSb1RxRdy, IoPass Ad1Tab1e LABEL DWORD DD IoFmAstat. IoFmData. IoPass, IoPass CdTab1e LABEL DWORD DD Iowss, Iowss, Iowss. Iowss DD IoCdAddr, IoCdData, IoPass, IoPass SystemTime DD 0 C1 1: entCr3 on ? C11enpTab LABEL FWORD cT1im1t ow ? cT1addr DD ? Regsave DD ? Pmoest LABEL FWORD Pooffset DD ? Poselector ow ? savecentries DD 6 DUP(?) cmdProc DD OFFSET Parsecmd Midimessage LABEL DWORD Midjstat DB 80h Mid1Data DB 00h, 00h. 00h FreqTab1e LABEL WORD ow 8000, $513. 16000, 11025 ?CA 02265567 1999-03-10 wo 98/1 1439 52 PCT/US97/15813 ow 27429. 13900. 32000, 22050 Dw 22050, 37800, 37800, 44100 Dw 48000, 33075, 9600. 6615 IFE WIN_CODE ALIGN 4 DB 256 DUP(0eeh) StackTop LABEL NEAR Loca1stack LABEL FWORD Lsoffset DD OFFSET StackTop LSse1ector ow ? spsave LABEL FWORD Ssoffset DD ? ssse1ector Dw ? ENDIF PUBLIC vF1ags vF1ags Dw 000h sbF1ags ow O000h Sbsrate pw 11025 Dmacount LABEL WORD DmaCountL DB 0 Dmacountu DB 0 AutoB1k LABEL WORD AutoB1kL 08 10h AutoB1kU DB 00h Pagenegs D8 87h, 83h, 81h. 82h MidiDatC DB 1 Midicurc DB 0 Mpuoata D8 00h Mpustat DB 10l11111b IF WIN_CODE PUBLIC ExtMidi Extmidi DB 0 PUBLIC _Synthvo1L _Synthvo1L DB 7fh PUBLIC _SynthVo1R _Synthvo1R DB 7fh ENDIF TagB te DB 80h To 9 e DB 0 SB rstat DB 00h S Accum DB Oaah sbxorPat DB 96h Tconst DB Offh FmAddr DB 01h Fmstat DB 06h CdAddr DB 40h wssswtch on ooh Stkswtch DB 00h PUBLIC Activecount Activecount DB ? IFDEF DOS_DEBUG Debugayte DB '0' ENDIF IF WIN_CODE vxD_LoCKED_DATA_ENDS ELSE .TEXT ENDS ENDIF SUBSTITUTE SHEET (RULE 26) ?CA 02265567 l999-03- 10 W0 98/ 1 1489 PCT/U S97/ 15813 _53- END SUBSTITUTE SHEET (RULE 26) ?CA 02265567 1999-03-10 wo 93/1 1439 PCT/US97/15813 -54- APPENDIX B .386p INCLUDE vivo.inc NUM_CODEPAGES EQU 25 NMI_INT EQU 02h TIMER_INT EQU 08h DOS_SETVECT EQU 25h DOS_TSR EQU 31h DOS_GETVECT EQU 35h DOS_FREE EQU 49h DOS_MODIFY EQU 4ah PARMBLK STRUCT envse wORD cmdof wORD cmdse WORD fcblo f WORD fcblse WORD fcb2of WORD fcb2seg WORD PARMBLK ENDS W) .0 .0 "Q .\) W) .9 _TEXT SEGMENT DWORD PUBLIC USEl6 'CODE' ASSUME CS:_TEXT, dS:_TEXT ORG 0100h start: jmp Entry ; Resident Data (non-discardab1e) starts here ALIGN 2 Fromscope LABEL NEAR vivosentries DD 6 DuP(?) xmsPaddr LABEL DWORD xP1ower Ow ? xPupper ow ? NumCodePages Dw 0O0Oh Hwconfig LABEL NEAR Baseport Dw ooooh wavePort Dw ? 0ttoPort Ow ? waveIrq DB ? Midixrq DB ? Omachan DB ? Extmidi DB ? sb£nab1e DB ? synthvo1 DB ? waveVo1 DB ? CdAuxVo1 DB ? BoardType DB ? ALIGN 2 Sharedoata LABEL NEAR Int67Return LABEL DWORD I67Roffset Dw ? I67Rsegment ow ? v86Return LABEL DWORD V86Roffset ow ? v86Rseg@ent Dw ? GetPmiD1 Dw ? SUBSTITUTE SHEET (RULE 26) ?W0 98/1 1489 DosLink DLoffset DLsegment MuxLink MLoffset MLsegment TimerLink TLoffset TLsegment F1ags FLAG_wIN Mjdjpic Mjdyvect M1d1unmask CA 02265567 1999-03-10 -55- LABEL DWORD ow ? ow 7 LABEL DWORD ow 7 DW 7 LABEL DWORD ow ? DW ? DW 0 EQU 0 ow 0021h DB 08h DB ? IFDEF DOS_DEBUG DebugPtr ENDIF ow 2*(80*O + 0) ; Resident Code (non-d1scardab1e) starts here IFDEF DOS_DEBUG DbPutCh PROC push push mov mov mov mov add POP POP ret DbPutCh ENDP DbPut8yte paoc push push push push mov mov mov mov @@1: ro1 mov and cmp Jb add Jmp add mov add GNP Jb . X0!‘ @@2: @@3: nba: es d1 di.0b000h ; apw es.di di.cs:DebugPtr es:[di].a1 cs:DebugPtr,4 di es cx dx di es di.cs:DebugPtr dx.0bO00h es,dx cx,2 d1.a1 d1.0fh d1.0ah @@2 d1,'A' - Oah SHORT @@3 d1.'0' es:[di],d1 di,2 di,2*80*24 nba di.di SUBSTITUTE SHEET (RULE 26) PCT/US97/15813 ?W0 98/1 1489 Toop mov add GNP 3b xor nbb: mov mov P°P POP POP POP ret DbPut8yte ENDP DbPutword PROC push push push push l'l‘|0V mov mov ITIOV @@1: ro1 mov and 9”? Jb gdd JMP add @@2: @@3: mov add cmp 3b xor nwa: Toop mov add Gmp Jb xor nwb: mov mov POP POP POP POP ret DbPutWOPd ENDP ENDIF CA 02265567 1999-03-10 -55- @@l BYTE PTR es:[di],' ' d1.2 di,2*80*24 nbb di,di BYTE PTR es:[di].'*' cs:DebugPtr,di es di dx cx cx dx di es di,cs:DebugPtr dx,0b00Oh es,dx cx,4 d1,'A' - Oah SHORT @@3 d1.'0' es:[di],d1 d’ 2 1. di,2*80*24 nwa di,di @@1 BYTE PTR es:[di],' ' di,2 di,2*80*24 nwb di.di BYTE PTR es:[qi].'*' cs:DebugPtr,d1 es di dx cx Nmilsr PROC FAR push push ax dx SUBSTITUTE SHEET (RULE 26) PCT/US97/15813 ?CA 02265567 1999-03-10 W0 98/1 1489 -57- mov dx,cs:BasePort add d1,NMIsTAT_oFF in a1.dx in a1,6lh and a1,0fh or a1.08h out 61h.a1 and a1,07h out 61h.a1 pop dx pop ax 1ret Nmilsr ENDP Midilsr PROC FAR bt cs:F1ags,FLAG_wIN jnc midoit 1ret midoitz push ax push bx mov ax,Odee1h mov bh,00h int 67h pop bx _ _ pop ax m1ex1t: iret Midilsr ENDP DOSISP PROC FAR bt cs:F1ags,FLAG_wIN jnc didoit Jmp cs:DosLink didoit: cmp ah,DOS_SETVECT je disvect Jmp cs:DosLink disvect: qmp a1.02h Je diskip cmp a1,cs:Midivect je ?sHp_ Jmp cs:DosL1nk diskip: _ 1ret DOSISP ENDP MUXISF PROC FAR pushf cmp ax.1605h je wstrt cmp ax.1606h je wstop mi1ink: 909* . Jmp cs:MuxL1nk wstrt: bts cs:F1ags,FLAG_wIN push ax push dx mov dx,cs:BasePort add d1.CONTROL_DFF xor a1,a1 SUBSTITUTE SHEET (RULE 26) PCT/U S97/ 15813 ?W0 98/1 1489 out add out POP 9°” JMP btr push push wstop: I mov mov out inc mov out dec mov out inc mov dec wnosb: out Don P09 Jmp MUXISF ENDP CA 02265567 1999-03-10 -58- dx,a1 d1,NMICTL_0FF-CONTROL_OFF dx,a1 dx ax mi1ink cs:F1ags.FLAG_wIN ax dx dx,cs:wavePort a1.40h OR CD_CONFIG dx.a1 d1 a1,04h dx,a1 d1 a1.CD_ADLVOL dx.a1 d1 a1,8ch d1 a1,CD_ADRvoL dx,a1 d1 a1,8ch dx,cs:BasePort d1.CONTROL_0FF a1,08h dx.a1 d1,NMICTL_OFF-CONTROL_OFF a1.0aOh cs:SbEnab1e,00h wnosb a1,40h dx,a1 dx 35 . m111nk TimerIsr PROC FAR bt jnc , , JMD t1do1t: push push mov in and out in and out 3 xor out POP P°P Jmp Timerlsr ENDP c§:F]ags.FLAG_wIN t1do1t _ cs:T1merL1nk ax dx dx,cs:MidiPic a1,dx a1.cs:Midiunmask dx.a1 a1,61h a1.07h 61h,a1 a1,a1 70h.a1 dx ax _ _ cs:T1merL1nk SUBSTITUTE SHEET (RULE 26) PCT/US97/15813 ?CA 02265567 1999-03-10 W0 98/1 1439 PCT/US97/15813 -59- GetPmi: push eax push cx mov eax,cs:xmsPaddr shr eax,1O and a1,0fch add ax,cs:GetPmiDi i67p1a: mov DWORD PTR es:[di].0fffff067h add d1,4 cmp d1.ax jb i67p1a mov eax.cs:xmsPaddr mov a1.67h mov cx,cs:NumcodePages i67p1b: mov es:[di],eax add di,4 add eax,1000h 1oop i67p1b mov bx,oFFSET vivocentries mov cx,6 i67g1p: mov eax.cs:[bx] add bx.4 mov [si].eax add 51,4 1oop 167 1p sub si, 4 mov ebx.14h pop cx pop eax jmp cs:Int67Return Fixup: mov ax,0dee0h int 67h jmp cs:v86Return TsrEnd LABEL NEAR ; Init Data (discardab1e) starts here ALIGN 2 xmsEntry LABEL DWORD : XMS far-ca11 entry point xEoffset ow ? xEsegment Dw ? xmsHand1e ow ? ; our XMS chunk hand1e Toscope LABEL NEAR ; discardable data sent to ScoPE.ExE EmmCr3 DD ? Emmcdt DF 7 Emmxdt DF ? Dw OFFSET Fromscope ow OFFSET Hwconfig DW OFFSET GetPmi Dw OFFSET Fixup Dw OFFSET sharedoata ; param struct for .ExE spawning Paramalock PARMBLK < ?, OFFSET Param, ?, Sch, ?, Gch. 7 > Fi1eHand1e ow 0 SsPath DB 65 DUPC?) vscape32 DB '\VSCAPE32.BIN',0 ssconfig as '\SSCONFIG.EXE'.0 scope as '\scoPE.ExE'.0 Dos4Gw DB '\Dos4Gw.ExE',0 SUBSTITUTE SHEET (RULE 26) ?W0 98/11489 Quiet Param Tmpsuff CA 02265567 1999-03-10 -50- on 'DOS4G=QUIET',O ca 127 oup(' ') DB 128 oupc?) ; Init code (discardab1e) starts here IFDEF DOS_DEBUG Printchar PROC push push mov mov int POP POP ret Printchar ENDP Printword PROC push push push mov @@1: r0} mov and ‘?"'P 3b qdd JNP add push mov ca11 DP oop r01 @@2: @@3: P0P POP POP ret Printword ENDP Printnet PROC push push mov mov int mov int DOD POD ret Printket ENDP ax dx d1,a1 ah,02h 21h dx ax ax cx dx cx,4 ax,4 d1.a1 d1.0fh d1.0ah @@2 d1,'A' - Oah SHORT @@3 d1,'0' ax a1.d1 Printchar ax @@1 ax,4 dx CX BX ax dx ah.02h d1.0dh d1,0ah 21h dx ax SUBSTITUTE SHEET (RULE 26) PCTlUS97l15813 ?W0 98/1 1489 Printstr PROC @@1: @@2: push push push mov mov 1nc qr 32 1nt Jmp POP POP DOP ret Printstr ENDP ENDIF PrintMsg PROC @@1: @@2: push mov push push push HIOV mov mov inc or 'z 1nt Jmp mov POP D09 POP POP ret PrintMsg ENDP wordTostr PROC @@1: @@2: @@3: push push ITIOV ro1 mov and ‘?"‘P 3b gdd Jmp add mov 1nc 1oop CA 02265567 1999-03-10 -61- d].es:[di] d1 d1.d1 @@2 21h SHORT @@1 di dx ax bp bp.sp X a dx si si,[b?+2] ah.02 d1_.[s1'] 51 d1,d1 @@2 21h SHORT @@1 [bp+2].si si dx ax bp @ d1.'A' — Oah SHORT @@3 d1,'0' es:[di],d1 di @@1 SUBSTITUTE SHEET (RULE 26) PCT/US97/ 15813 ?CA 02265567 1999-03-10 W0 98/1 1489 PCT/US97/ 15813 -62- mov BYTE PTR es:[di].0 inc di pop dx pop cx ret wordToStr ENDP - strcpy ; Inputs: dszsi - source string _ ; es:di - destination string ; Return: Nothing. A11 regs are 1eft unaffected except ... , is wi11 point to the byte immediate y fo11owing the 1ast ; destination byte that was copied to. 5 di — t trcpy PROC push ax ; save regs push si @@1: _ mov a1, si} ; copy the string mov es: di .a1 inc si inc di cmp a1,0 jne @@1 pop si ; restore regs and exit pop ax ret strcpy ENDP Entry: ; string ops forward a1ways c1d : print a he11o dorks message ca 1 Printnsg DB 0dh,0ah,' soundscapevIvo(TH) Initia1ization Driver, version 3.22.'.0dh,Oah DB ' Copyright(c) 1995-1996. ENSONIQ Corp., A11 Rights Reserved.'.Odh.0ah.0 ; if we need to. free a11 but our 64k so we can spawn 1ater mov ax.sp cmp ax.0fffeh jne csizok mov bx,cs mov es.bx mov bx.1000h mov ah,DOS_MODIFY int 21h csizok: : see if 1oader is command she11 - if not, assume .com and resize mov ax.cs:[0016h] mov es.ax mov bx,es:[0016h] cmp ax x je psizok mov ~ es.ax mov bx,1000h mov ah,DOS_MODIFY int 21h psizok: ; get the int 67 vector. make sure we got a memory manager mov ax.(DOS_GETVECT SHL 8) OR 67h int 21h mov ax.es or ax,ax jnz emvok SUBSTITUTE SHEET (RULE 26) ?CA 02265567 l999-03- 10 wo 93/11439 PCT/US97/15813 -53- ca11 Printmsg DB 0dh,0ah.O7h, error: Memory Manager not detegted.'.Odh.0ah DB ' Soundscapevlvo requires EMM386 or s1mi1ar.',0dh.0ah,0 jmp exit emvok: ; see if we're a1ready 1oaded mov ax,0dee1h mov bx.ObSSh int 67h cmp b1,0aah jne ssnpres ca11 Printmsg _ DB Odh,0ah,' ... soundscapevlvo driver 15 current1y Toaded ...',0dh.Oah,0 jmp exit ssnpres: ; Tocate our path and save it xor i, i mov es,cs:[002ch] mov cx,0ffffh xor a1,a1 env1p: repne scasb cmp a1.es:[di] jne SHORT env1p mov bx.di add di,3 push ds _ mov si,d1 mov ax.es mov ds,ax mov di,OFFSET ssPath mov ax.cs mov es,ax ca11 Strcpy pop ds mov di,OFFSET SsPath xor a1,a1 V- repne scasb pushf std mov a1,'\' repne scasb popf inc di mov BYTE PTR [di],O ; set the_1oca1 quiet environment var for 46w spawn mov 1, x mov es.cs:[OO2ch] mov si.oFFSET Quiet ca11 Strcpy mov BYTE PTR es:[di],0 : bui1d the parameter 1ine for config spawn mov di,oFFSET Param+2 mov ax,ds mov es.ax mov ax,oFFsET Hwconfig ca11 wordToStr : setup config offset arg mov BYTE PTR [di-1].’ ' mov ax,ds ca11 wordTostr ; setup segment arg mov BYTE PTR [di—1],0dh sub di,oFFSET Param+2 ; add 1ength mov ax,di mov Param,a1 ; build the fi1ename for the config code mov si.oFFsET ssPath mov di,0FFSET Tmpauff mov dx.ds SUBSTITUTE SHEET (RULE 26) ?CA 02265567 1999-03-10 WO 98/11439 PCT/US97/15813 -64- mov es.dx ; first copy path ca11 §trCpy dec di mov si.oFFSET Ssconfig ; append fi1ename ca11 Strcpy mov bx.oFFSET Param81ock ; setup param block mov ax.cs:[0O2ch] mov (PARMBLK PTR bx ).envseg.ax mov (PARMBLK PTR bx ).cmdseg,ds mov (PARMBLK PTR bx ).fcblseg.ds mov (PARMBLK PTR bx ).fcb2seg.ds mov dx,oFFSET Tmpauf mov ax.ds mov es.ax mov ax.4bOOh ; and spawn the .exe int 21h jnc cfgran ca11 Printnsg DB 0dh.Oah.O7h. error: Cou1d not execute sSCoNFIG.ExE.‘,0dh,0ah,O jmp exit cfgran: cmp BasePort.0 jne cfgok Jmp exit cfgok: ; see if we have to bai1 now ... mov di,O080h xor cx.cx mov c1,[di] ; 1ook for /N cmd 1ine arg or c1,c jz noki11 dec cx inc di mov ax,ds mov es,ax mov a1.‘/' repne scasb jnz noki11 mov a1,[di] and a1,0dfh cmp a1.'N' jne noki11 cal} Printms DB 0dh,0ah,' In1tia1ization comp1ete. nos drivers NOT Toaded.',0dh.0ah,0dh,0ah.0 jmp exit noki11: ; setup some Hw-dependent vars mov c1,MidiIrq cmp c1,08h jb mvrset mov MidiPic.00a1h mov Midivect,70h mvrset: and c1,07h add Midivect.c1 mov a1,1 sh1 a1.c1 not a1 _ mov MidiUnmask.a1 ; see if we have an xMs driver mov ax,4300h int Zfh cmp a1.80h je xmspr ca11 Printmsg DB 0dh,0ah,07h. error: xMs services were not detected.'.0dh,Oah,0 jmp exit xmspr: ; get the XMS contro1 function entry point mov ax.4310h int Zfh SUBSTITUTE SHEET (RULE 26) ?CA 02265567 1999-03-10 WO 93/11439 PCTIUS97/15813 -55- mov xEoffset,bx mov xEsegment,es ; get enough xMs for our 32-bit code mov dx,(4 * NUM.CODEPAGES) mov ah,09h ca11 xmsentry or ax,ax jnz xmsok ca11 Printnsg ‘ QB 0dh,0ah,07h, error: cou1d not a11ocate requ1red Extended Memory.',0dh,0ah,0 Jmp ex1t xmsok: _ ; 1ock the xMs b1ock (hand1e 1n dx). save phys addr mov ah,0ch ca11 xmsantry OI” 3X ax jnz xmiok ca11 Printnsg DB 0dh,Oah.0Zh, error: Cou1d not 1ock Extended Memory.'.0dh.0ah.0 jmp xfex1t xm1ok: mov xP1ower.bx mov xPupper,dx : make sure we're be1ow 4M mov eax,xmsPaddr add eax.((NUM_CODEPAGES SHL 12) - 1) cmp eax.4000O0h jb xm4ok ca11 Printus odh 0 has Odh,0ah,07h. error: Cou1d not a11ocate Extended Memory be1ow 4 Mbyte boundary.‘ 1 I a DB ' Try Toading sSINIT.coM before sMARTDRv.ExE',0dh,0ah.O fxexit: jmp xuexit xm4ok: _ ; get the EMM386 env1ronment and data for scope.exe mov eax.cr3 mov Emmcr3,eax sgdt EmmGdt S1dt EmmIdt ; build the parameter 1ine for scope spawn mov d1.0FFsET Param+2 mov ax,ds mov es,ax mov s1,oFFsET ssPath ; setup fpath and fname for DOS4Gw ca11 Strcpy dec di mov si.oFFsET scope ca11 %trcpy mov BYTE PTR di-1],’ ' mov BYTE PTR di].o mov ax.OFFsET Toscope ca11 wordTostr ; setup data-out offset arg mov BYTE PTR [di-1],’ ' mov ax,ds ca11 wordTostr : setup segment arg mov BYTE PTR [di-1].0dh sub di,oFFsET Param+2 ; add 1ength mov ax,di mov Param,a1 ; bui1d the fi1ename for the scope (oos4Gw) code mov si,oFFSET ssPath mov d1.0FFSET Tmpauff mov dx.ds mov es,dx ; first copy path ca11 Strcpy dec di mov si,oFFSET Dos4Gw ; append filename ca11 strcpy SUBSTITUTE SHEET (RULE 26) ?CA W0 98/1 1489 scpran: scpok: umwt1po: umwt1pi: 02265567 1999-03-l0 PCT/US97/ 15813 setup param biock and spawn the .exe execute SCOPE.EXE.',0dh,Oah,0 insta11 NMI service insta11 MIDI IRQ service save DOS vector insta11 our DOS service SBVE MUX VECIOF insta11 our Mux service TIMeR_;NT save timer vector insta11 our timer service -65- mov bx,oFFsET ParamB1ock : mov dx,0FFSET Tmpsuff mov ax,ds mov es.ax mov ax,4b0Oh ; int 21h jnc scpran ca11 PrintMsg D8 Odh,Oah,07h, error: Cou1d not jmp fxexit cmp NumCodePages,0 jne scpok Jmp fxexit mov dx,oFFSET Nmixsr : mov ax.(DOS_SETVECT SHL 8) OR 02h int 21h mov dx.0FFSET Midilsr : mov a1.Midivect int 21h mov ax.(DOS_GETvECT SHL 8) OR 21h int 21h ; mov DLoffset.bx mov DLsegment,es mov dx,OFFSET Doslsr ; mov ah,DOS_SETVECT int 21h mov ax,(DOS_GETVECT SHL 8) on zfh int 21h ; mov MLoffset,bx mov MLsegment,es mov dx.OFFSET MuxIsr ; mov ah,DoS_SETvECT int 21h mov ax.(DOS_GETVECT SHL 8) OR int 21h ; mov TLoffset,bx mov TLsegment.es mov dx,oFFsET TimerIsr ; mov ah,DoS_SETvECT int 21h ; ca11 synth—init and enab1e otto ints mov ax,0dee1h mov bh,O1h int 67h mov dx.BasePort add d1,CONTROL_OFF mov a1,08h out dx,a1 ; wait, then un—mute the synth mov dx,BasePort add d1,0DADDR_OFF mov cx,000fh push cx mov cx,0ffffh in a1,dx 1oop umwt1pi op cx oop umwt1po cmp BoardType,00h jne unmvcr mov dx,cs:wavePort SUBSTITUTE SHEET (RULE 26) ?CA 02265567 1999-03-l0 PCT/US97/15813 DB 0dh.0ah.' Ingtia1ization comp1ete.'.0dh.0ah.0dh,0ah,0 ; free our 1oca1 environment seg ; terminate / stay resident W0 98/1 1489 -57- mov a1 , CD__PINCTL out dx,a1 inc dx in a1.dx or a1,40h out dx,a1 jmp unmdone unmvcr: mov dx,cs:wavePort mov ah,synthvo1 xor ah,7fh shr ah.2 mov a1,CD_LINELVoL out dx,a1 inc dx mov a1,ah out dx,a1 dec dx mov a1.CD_LINERVOL out dx,a1 inc dx mov a1,ah out dx,a1 unmdone: ; enab1e system NMI, then VIVO NMI in a1, and a1,03h or a1,04h out 61h,a1 xor a1,a1 out 70h,a1 mov dx.BasePort add d1,NMICTL_OFF mov a1,0a0h cmp SbEnab1e,0 je sb1don or a1,40h sb1don: out dx,a1 TandsR: ca11 Printns mov es.cs:[O02ch] mov ah.DOS_FREE int 21h mov dx,(0FFSET TsrEnd + 000fh) shr dx.4 mov ax,(DOS_TSR SHL 8) int 21h xuexit: ; un1ock XMS memor¥ b1ock mov dx,xmsHand e mov ah.0dh ca11 xmsEntry xfexit: ; free XMS memory b1ock mov dx.xmsHand1e mov ah.0ah ca11 xmsEntry exit: ; get outta here ret .TEXT ENDS END start SUBSTITUTE SHEET (RULE 26) ?CA 02265567 1999-03-10 W0 98/11489 68 PCT/US97/15813 APPENDIX C #inc1ude <stdio.h> #inc1ude <std1ib.h> #inc1ude <i86.h> #define NUM_CODEPAGES 25 /* number of 4k pages occupied by V32 code */ //#define DEBUG /* some standard t pedefs ... */ typedef unsigned c ar BYTE: typedef unsigned short WORD; typedef unsigned 1ong DWORD; /* The fo11owin? structure is the data passed in from SSINIT */ typedef struct owono CR3; /* EMM's CR3 */ WORD GdtLimit; /* EMM's GDT Timit. Tinear address */ DWORD GdtLaddr; WORD IdtLimit; /* EMM's IDT Timit, Tinear address */ DWORD IdtLaddr; WORD Dooffset; /* output data offset */ WORD Hwoffset; /* HW confi data offset */ WORD GetPmioff; /* offset 0 V86 get PMI return hand1er */ WORD Fixupoff: /* offset of V86 switch return hand1er */ WORD sharedoff; /* offset to V86/V32 shared data area */ } DATA_IN; /* The fo11owing structure points to SSINIT's resident data area */ typedef struct_ _ _ DWORD V1VoGentr1es[6]; /* VIVO GOT entries for VCPI get PMI */ DWORD xmsPaddr; /* phys addr of Extended Mem '/ WORD NumcodePages; /* number of 4k V32 code pages */ } DATA_RES; /* The fo11owin structure is SSINIT's HW config data */ typedef struct WORD BasePort; /* Gate Array base port */ WORD WavePort; /* cooec base port */ WORD synthPort; /* Otto base port */ BYTE Wavexrq; - /* CoDec/SB IRQ */ BYTE Midilrq; /* Synth IRQ */ BYTE Dmachan; /* CODeC/SB DMA channe1 */ BYTE Extmidi: /* Externa1 MIDI enab1e */ BYTE sbEnab1e; /* SB emu1ation enab1e */ BYTE SynthVo1; /* Synth Vo1ume */ BYTE WaveVo1; /* Wave vo1ume */ BYTE CdAuxVo1; /* CD/Aux voiume */ BYTE BoardType; /* vivo rev number */ } HW_CONFIG: /* The fo11owin structure is the config data at the top of the V32 code */ typedef struct B YTE JumpTab1e[0x1c ; /* jump instr's for mu1tip1e entry pts */ DWORD VivoGentries[6 ; /* the VIVO VCPI Get PMI GDT entries */ DWORD VcpiGentries[6]; /* the real VCPI Get PMI GDT entries */ DWORD sharedDataP; /* 1inear addr of V86/V32 shared data */ DWORD Midivectoff; /* IDT MIDI vect offset from NMI */ DWORD Getpmioff; /* QWORD far ptr to V86 Get PMI hand1er */ DWORD GetPmiseg: DWORD Fixupoff; /* QWORD far ptr to V86 switch fixup hand1er */ DWORD Fixupsegz DWORD I67Linkoff; /* PM 1ink to the rea1 Int 67 hand1er */ WORD I67LinkSe1; DWORD . Vcpientryoff; /* PM entry point to the rea1 VCPI hand1er */ WORD VcpiEntryse1; WORD Hardwareoptions; /* bit fie1d for board type */ WORD BasePort: /* dup1ication of hardware config for V32 */ WORD wavePort; WORD SynthPort: BYTE WaveIrq; BYTE Midilrq; BYTE Dmachan; BYTE ExtMid1; SUBSTITUTE SHEET (RULE 26) ? CA 02265567 1999-03-10 W0 98/1 1489 69 PCT/US97/15813 BYTE Synthvo1L; BYTE SynthVo1R; } V32_CONFIG; /* The fo11owin structure is the Dos mem used in the VCPI Get PMI ca11 */ typedef struct ? _ DWORD PageTab1e[0xO400]: DWORD vcpiGentries[6]; BYTE DosStack[0x0400 - 4*6]; } DOS_MEM; owoao DosMa11oc(Dw0RD size); void DosFree(woRD se1ector); DWORD GetGDT(); DWORD Getvcpi(woRD dmseg); DWORD GetCR3(); /* This function returns the 386 CR3 va1ue */ #pragma aux GetCR3 = \ mov eax.cr3" \ va1ue [eax]; void F1ushTLB(void); /* This function f1ushes the page tab1e TLB */ #pra9ma aux F1ushTLB = \ mov eax.cr3" \ "mov cr3,eax" \ modify [eax]; void SetI(void); /* This function disabies interrupts */ #pra?ma_aux Setl = sti"; void c1rI(void); /* This function enab1es interrupts */ #pragm?_aux C1rI = C 1 ll ; void main(int argc, char *argv[]) { #ifdef DEBUG FILE *fd; #endif FILE *fp = 0: DATA_IN "'pd'i ; DATA_RES *pdr; Hw_CONFIG *phw; V32_CONFIG *pv32, DOS_MEM far *pdm; DWORD *pd4g0, *pxms, *pgdt. *pidt, *ppdir; owoao vo1ati1e *ppta ; owoao tmp; WORD dioffset, dooffset, dsegment; WORD i, 3, dmseg, dmse1 = 0; BYTE midivect; char *pc; static char fname[128]; static owono TmpBuff[1024]; #ifdef DEBUG fd = fopen("SCOPE;DBG", "w"); #endif /* make sure we got the right arg count, make pointers and midivect */ if( argc < 3 return; dioffset = (WORD) strtou1(argv[1]. NULL, 16); dsegment = (WORD) strtou1(argv[2], NULL, 16): pdi = (DATA_IN *) (((DwoRD) dsegment << 4) + dioffset): pdr = (DATA_RES *) (((DwORD) dsegment << 4) + pdi7>DoOffset); phw = (Hw_CONFIG *) (((DwoRD) dsegment << 4) + pdi->Hwoffset); midivect = (phw—>MidiIrq < 8 ? 0x08 : 0x68) + phw->MidiIrq; #ifdef DEBUG SUBSTITUTE SHEET (RULE 26) ?CA 02265567 l999-03- 10 W0 98/11489 PCT/US97/15813 -70- fprintf(fd, "\npointers ...\n"); fprintf(fd, "P V86 non—res %081x\n", pdi); fprintF(fd, "P v86 res %O81x\n", ?dr); fpr1ntf(fd, "P v86 Hw %081x\n", p w); fpr1ntf(fd. "\nEMM context ...\n' ; fprjntf(fd, "CR3 %O81x\n", di->CR3); fpr1ntf(fd, "GDT %081x %04x n”, pdi->GdtLaddr. pdi->GdtLimit); dfgr1ntf(fd. "IDT %O81x %04x\n", pdi->IdtLaddr, pdi->IdtLimit); #en i /* setup the oos4Gw page tab1e-zero-pointer */ pd4g0 = (owoao *) (GetCR3() & 0xfffff0o0uL); pd4g0 = (DWORD *) (*pd4g0 & 0xfffff0O0UL); /* setup Taddr 0x18000O for EMM pa e dir, 0x181000 for var page tab ptr */ *(pd4g0 + 0x0180) = (pdi->CR3 & Ox ffffO00UL) I 0X67U; ppdir = (DwoRo *) Ox180000UL; pptab = (DWORD vo1ati1e *) 0x181000uL; /* point pptab at EMM's page tab1e for the GDT. create a ptr */ *(pd4g0 + 0x0181) = *(ppd1r + (pd1->GdtLaddr >> 22)); F1ushTLB(); /* setup page tab1e and pointer for EMM's GDT */ *(pd4g0 + 0x0182) = *(pptab + ((Pd1->GdtLaddr » 12) & 0x0o0o03ffuL)) | 0x67u; *(pd4g0 + 0xO183) = *(pd48O + 0x01$2) + Ox1000U; pgdt = (DWORD *) (0x1820o UL I (pd1->GdtLaddr' & 0x00000fffuL)); /* point pptab at EMM's page tab1e for the IDT. create a ptr */ *(pd4g0 + Ox0181) = *(ppd1r + (pd1—>IdtLaddr >> 22)); F1ushTLa(); /* setup page tab1e and pointer for EMM's IDT */ *(pd4gO + 0x0184) = *(pptab + ((pd1—>IdtLaddr >> 12) & 0xOO0003ffuL)) I 0x67U: *(pd4gO + 0x01B5) = *(pd480 + 0x0184) + 0x1000U: pidt = (DWORD *) (0x18400 UL I (pdi->IdtLaddr & 0x000o0fffuL)); /* open the code fi1e in current .exe's directory */ strcpy(fname, argv[0]); pc = fname; whj1e( *pc++ ) ; wh11e( *7-pg != '\\' ) : *++pc = \O ; strcat(fname, "VscAPE32.BIN"); 1f( !(fp = fopen(fname, "rb")) ) { _ pr1ntf("\007 error: cou1d not open f11e \"%s\".\n", fname); goto exit; [* get the DOS memory for the GetPMI ca11, setup far ptr */ 1f( !(tmp = DosMa11oc(5*1024UL)) ) { pr1ntf("\0O7 error: cou1d not a1ocate oos memory.\n"); goto exit; dmsel (WORD) (tmp >> 16); dmseg (WORD) tmp; * (DWORD *) &pdm = OUL; * ((w0RD *) &pdm + 2) = dmse1; /* get the first chunk of our fi1e */ fread(TmpBuff, 1, 1024, fp); /* setup V32 config data pointer */ pv32 = (V32_CONFIG *) &Tmp8uff; /* make the Get PMI ca11, copy VCPI data into V32 config */ pv32->vcpiEntryoff = Getvcpi(dmseg); for'(1'=O;'i<6;++‘i) pv32->vcpiGentr1es[i] = pdm->vcpiGentries[i]: /* setup the vrvo GDT entries in V32 and data—out mem */ pv32->vivoGentries[0] = pdr—>vivoGentries[0] = §v32—>vivoGentr1es[2] = pdr->vivoGentries[2] = (pdr->xmsPaddr << 16 | Oxffffu; tmp = (pdr—>xmsPaddr & 0xff00O000UL) ((pdr—>xmsPaddr >> 16) & 0xO00000ffUL) I 0x004f9300UL; SUBSTITUTE SHEET (RULE 26) ?CA 02265567 1999-03-10 wo 93/1 1489 1 PCT/US97/15813 pdr->vivoGentries 3 = tmp; pv32—>vivoGentries 4 pdr->v1voGentries 4 = 0xOO0OffffUL; pv32->vivoGentries 5 pdr->v1voGentr1es S u Ox00cf9300uL; /* fi11 out the rest of the V32 config memory */ pv32->sharedDataP c ((owono) dsegment << 4) + pdi->sharedoff; pv32->Midivectoff = (DWORD) gmidivect - 2) << 3; pv32~>GetPmiOff = (DWORD) pq1—>§etPmioff: pv32->Fixupoff - (DWORD) pdi->F1xupoff; pv32->GetPmiseg - pv32-§F1xupSeg - (owono) dsegment; pv32—>I67Linko f - (*(p1dt + (0x67u << 1) + 1) & 0xffff0O00UL) l (*(pidt + (0x67U << 1)) & Qx00OOffffUL); pv32->167Linkse1 -_- (wono) ("(p1dt + (0x67u « 1)) » 15); pv32->Hardwareopt1ons - 1 << phw—>BoardType; pv32->BasePort - phw—>BasePort; pv32->wavePort - phw—>wavePort: pv32—>synthPort = phw->synthPort; pv32->waveIrq = phw->waveIrq: pv32->MidiIrq - phw->Mid1Irq: pv32->omachan - phw—>nmachan: pv32->ExtMidi - phw->ExtMid1 & Ox7f; if( phw->BoardType -- 0x00 ) 1 pv32->synthvo1L - pv32->synthvo1R - phw->synthvo1 & 0x7f; e se pv32->Synthvo1L - pv32->synthvo1R = 0x7f; #ifdef DEBUG fprintf(fd. "\nv32 Data ...\n"); pv32->vivoGentries 1 pv32->vivoGentr1es 3 pdr->VivoGentriesE1§ = tmp I 0x0oooo8o0uL; fprintf(fd. “vIvo GDT O %081x %O81x\n", pv32->vivoGentries 0 , pv32->vivoGentries 1 ); fpr1ntf(fd. "VIVO GDT 1 XO81x %O81x\n". pv32->vivoGentries 2 . pv32->vivoGentries 3 ): fprintf(fd, "vIvo GDT 2 %O81x X081x\n", pv32->vivoGentries 4 , pv32->vivoGentries S ); fprintf(fd, "VCPI GDT O %0B1x %081x\n". pv32->vcpiGentries 0 . pv32—>vcpiGentries 1 ); fprintf(fd, "VCPI GOT 1 %081x %081x\n". pv32->vcpiGentries 2 . pv32—>vcpiGentries 3 ): fprintf(fd. "VCPI GDT 2 %081x %O81x\n", pv32—>vcpiGentries 4 . pv32->vcpiGentries S ); fprintf(fd. "sharedDataP %081x\n", pv32->sharedDataP); fprintf(fd. "midivectoff %081x\n". pv32->MidivectOff); fprintf(fd. "v86GetPMI %081x %D81x\n", pv32->GetPmiSeg. v32—>GetPmioff); fprintf(fd. "v86Fixup %081x %O81x\n", pv32->FixupseE. pvgz->Fixupoff): fprintf(fd, "INT67 L1nk %O4x %081x\n". pv32->I67Lin Se , pv32->I67Linkoff); fpr1ntf(fd, "VCPI Entry %O4x %O81x\n", v32->vcpiEntryse1. pv32->vcpiEntryoff); fprintf(fd. "Hardware opts %O4x\n", pv3 ->Hardware0ptions): fprintf(fd, “Ports %04x %04x %O4x\n", pv32->aasePort. pv32->wavePort, pv32—>synthPort); fpr1ntf(fd. "IRQS %02x %02x\n". pv32->waveIrq. pv32->MidiIrq); # df$rintf(fd, "DMA %O2x\n". pv32->DmaChan); en 1 /* make entries in page tab1e at 0x200000+ for our code. make pointer '/ for( i = 0. tmp - (pdr—>xmsPaddr & 0xfffffO0OUL) | 0x67; i < NUM_CODEPAGES + 1; ++i. tmp += 0x10o0u ) '(pd4g0 + 0x0200 + i) - tmp; pxms - (DWORD ‘) (OXZOOOOOUL I (pdr->xmsPaddr & Ox0OO0OfffUL)); /‘ copy first fi1e chunk up to Extended Memory */ for( i - O: i < 256; ++i ) ‘pxms++ = TmpBuff[i]; /* now copy the rest of the code file up */ whi1e( !feof(fp) ) { ' = (fread(TmpBuff. 1, 1024. fp) + 3) >> 2; or( i - O: i < 3; ++1 ) } 'pxms++ - TmpBuff[1]; /* The next section wi11 fi11-in unused entries in the Dos4Gw */ / page tab1e at 1in-addr Ox180000+ and setup some pointers to a11ow */ /* us to access the page tab1e, GDT. and IDT of the EMM. */ 1 /* fi11 in the EMM's page-tab1e-zero with our xMs entries */ *(pd4g0 + 0xO181) = ‘ppdir; F1ushTLB(); for( i 2 (WORD) (pdr—>xmsPaddr >> 12). tmp = pqr—>xmsPaddr I 0x67U; 1 < (WORD) (pdr->xmsPaddr >> 12) + 25; ++1, tmp +- 0x1000U ) *(pptab + 1) = tmp; SUBSTITUTE SHEET (RULE 26) ?CA 02265567 1999-03-10 wo 93/1 1489 PCT/US97/15813 -72- /* find a GDT space to patch starting from top */. for( i = ((pdi->GdtLimit + 1) >> 2) — 2; i >= 2; 1 —= 2 ) if( !(*(?9dt + i + 1)) ) brea if( 1 < 2 ) { pr1ntf("\0O7 error: cou1d not insta11 service vectors.\n"); return; i —= 4; #ifdef DEBUG fpr1ntf(fd, "\nBase Se1ector %04x\n", 1 << 2); #endif _ _ /* patch the GDT with our three serv1ce entr1es */ *(pgdt + j) = *(pgdt + i_+ 2) = pdr->vivoGentr1es[0]; *(pgdt + 1 + 1) = pdr—>v1voGentr1esE1 : *(pgdt + 1 + 3) = pdr->vjvoGentrjes 3 ; *(pgdt + 1 + 4) = pdr—>v1voGentrjes[4]; *(pgdt + 1 + S) = pdr->v1voGentr1es[S]: /* in1t1a11ze some hardware ... */ inp(phw—>sasePort + 0x08); // NMI c1r outp(phw—>BasePort outp(phw->BasePort outp(phw->3asePort outp(phw—>BasePort outp(phw->BasePort outp(phw->BasePort outp(phw->8asePort outp(phw->BasePort outp(phw->BasePort 0x04, 0x04); outp(phw->BasePort 0x05. (phw—>waveIrq == 9 ? 0x00 : phw->waveIrq == 5 ? 0x04 : 0x08) I (phw—>Mid1Irq == 9 ? 0x00 : phw->M1diIrq == 7 ? 0x02 : Ox03)); outp(phw—>BasePort + 0x04. 0x06); outp(phw->8asePort + 0x05, 0x00); 0x02, 0x03); // UART reset 0x02, 0x00); 0x06, 0x00); // no Otto ints yet 0x08. Oxfe); 0x09, Oxaa); 0x08); 0x04, 0x03): 0x05, 0x80 I (phw—>DmaChan << 4)); ++++++++++ O X C N outp(phw->wavePort, Oxoc); outp(phw—>wavePort + 1. 0x50): outp(phw->wavePort, 0x49); outp(phw->wavePort + 1. 0x04); outp(phw->wavePort, 0x48); outp(phw->wavePort + 1, 0x00); outp(phw—>wavePort, 0x0a); outp(phw->wavePort + 1, 0x80); outp(phw—>wavePort. Oxlb); outp(phw->wavePort + 1. 0x08): outp(phw—>wavePort, 0x10); outp(phw->wavePort + 1. 0x80); outp(phw->wavePort. 0x11); outp(phw—>wavePort + 1. Oxco); outp(phw->wavePort. 0x00); outp(phw—>wavePort + 1. 0x8c); outp(phw—>wavePort. 0x01); outp(phw~>wavePort + 1. 0x8c); outp(phw->wavePort, 0x06); outp(phw—>wavePort + 1, (phw->wavevo1 A 0x7f) >> 1); outp(phw—>wavePort. 0x07): outp(phw->wavePort + 1, (phw->wavevo1 A 0x7f) >> 1); outp(phw—>wavePort, 0x02); outp(phw->wavePort + 1. (Dhw->cdAuxvo1 A 0x7f) >> 2); outp(phw->wavePort. 0x03); outp(phw->wavePort + 1, (phw->cdAuxvo1 A 0x7f) >> 2); /; ngg create the IDT entries for our NMI, MIDI. DOS and Int67 services */ C rI ; tmp = (DWORD) i << 18: *(p1dt (Ox02U << 1)) = tmp; *(p1dt + (0x02U << 1) + 1) = 0x00008e00UL: *(pidt + ((woRD) midivect << 1)) 3 tmp I 0x0004U; *(pidt + ((wORD) midivect << 1) + 1) = 0x00008e00UL; *(pidt + (Ox67U << 1)) = tmp | Ox00OcU; + SUBSTITUTE SHEET (RULE 26) ?CA 02265567 1999-03-10 wo 93/1 1439 73 PCT/US97/15813 *(pidt + (0x67u << 1) + 1) - OxOO00eeO0UL; SetI(): #ifdef DEBUG fprintf(fd, "\nv86 Resident Data ...\n"); _ . fprintf(fd. "VIVO GDT 0 %081x %O81x\n", pdr—>v1voGentr1es 0 , pdr—>vivoGentries 1 ); fprintf(fd. "vxvo GDT 1 %081x %081x\n",-pdr->vivoGentries 2 , pdr->vivoGentries 3 ); fprintf(fd. "VIVO GDT 2 X081x %O81x\n". pdr->v1voGentries 4 , pdr->vivoGentries S ); fprintf(fd. "XMS Paddr %081x\n“, pdr->xmsPaddr); df¥rintf(fd. "Num Code Pages %04x\n". pdr->NumcodePages); #en i /* fi11-out the rest of the resident data struct '/ _ pdr->NumcodePages - NUM_CoDEPAGES: exit: if( dmse1 ) DosFree(dmse1): if( fp fc1ose(fp); wifdef DEBUG fc1ose(fd); wendif FEIUFH; /* This function invokes the DPMI INT-31h ca11 for a11ocating Dos memory. */ owoao DosMa11oc(DwoRD size) { union REGS r; r.w.bx = (WORD) ((size + 15) >> 4); r.w.ax - OxO100; int386(0x31. &r. &r); if( r.w.cf1ag ) return OUL; return (r.x.edx << 16) I r.w.ax; /* This function invokes the DPMI INT—31h ca11 for freeing oos memory. */ void DosFree(woRD se1ector) { union REGS r; r.w.dx - se1ector: r.w.ax - Ox0101: int386(0x31. &r. &r); PBIUPH; } /' This function invokes the DOS-mode VCPI INT-67h ca11 for acquiring the */ /' protected—mode interface. */ owono Getvcpi(woRo dmseg) { union REGS r; struct SREGS 5; static struct 3 DWORD e 1: DWORD esi: DWORD ebp; DWORD zero; DWORD ebx: DWORD edx; DWORD ecx; owono eax; SUBSTITUTE SHEET (RULE 26) ?CA 02265567 1999-03-10 W0 93/11439 PCT/U S97/ 15813 -74- WORD f1ags; WORD es; woRD ds; WORD fs; WORD gs ; WORD 1p; WORD CS; WORD SD; WORD SS; } RmRegs = { OUL, OXIOOOUL. OUL, OUL, OUL, OUL, OUL, 0x0000de01UL, Ox3000. 0U, 0U. 0U. 0U, 0U, 0U, Ox1400U, OU}: RmRegs.ds = dmseg; RmRegs.es = dmseg; RmRegs.ss = dmseg; segread(&s): r.w.ax = 0x0300; r.w.bx = Ox0067: r.w.cx = 0; r.x.edi = (DWORD) &RmRegs; s.es = s.ds: 1nt386x(Ox31. &r, &r. &s); return RmRegs.ebx; SUBSTITUTE SHEET (RULE 26)

Claims (17)

What is claimed:
1. A method of providing device to an application running under a DOS extender within a protected-mode context created for said DOS extender within a DOS-based operating system environment of a processor at run-time, said protected-mode context created for said DOS extender including an interrupt descriptor table for said DOS extender (DOS extender IDT), comprising the steps of:
storing device emulation code at a predetermined address in a memory accessible to said processor;
detecting startup of said DOS extender;
upon detection of startup of said DOS extender, patching said DOS extender IDT to include a vector to said device emulation code for a predetermined interrupt; and when said processor detects said predetermined interrupt during execution of said application, said processor referencing said vector to said device emulation code patched into said DOS extender IDT.
2. The method of claim 1, wherein said predetermined address is in extended memory addressable by said processor, and said storing step comprises the step of storing said device emulation code at said predetermined address at boot-time.
3. The method of claim 1, wherein said DOS-based operating system environment includes a virtual control program interface (VCPI) through which said DOS extender acquires said protected-mode context, said detecting step comprising the steps of:
intercepting communications between said DOS extender and said VCPI during said execution of said application; and detecting startup of said DOS extender when a communication from said DOS extender to said VCPI is a request to obtain a protected-mode interface.
4. The method of claim 3, said patching step comprising the steps of:
causing protected-mode far calls from said DOS extender to said VCPI to pass through a far call entry point of a driver, said driver executing under the protected-mode context created for said DOS
extender; and said driver installing its interrupt vectors into the DOS
extender IDT upon receipt of said protected-mode far calls from said DOS
extender to said VCPI, said driver interrupt vectors including said vector to said device emulation code for said predetermined interrupt, thereby making said device emulation code available to said DOS extender and said application in said protected-mode context of said DOS

extender.
5. The method of claim 4, including the additional steps of:
at boot time, invoking said request to obtain a protected-mode interface from said VCPI and said VCPI returning a plurality of selectors and a VCPI entry point offset;
copying said plurality of selectors and said VCPI entry point offset into a data space shared between said driver and a terminate-and-stay-resident (TSR) initialization program;
copying said data space into a physical address of allocated extended memory addressable by said processor;
copying protected-mode executable code of said driver, including said device emulation code and code for processing said request to obtain a protected-mode interface, into said allocated extended memory;
saving a linear address of a protected-mode interrupt descriptor table for said DOS-based operating system environment (system IDT);
passing said physical address of said allocated extended memory and said linear address of said system IDT to said TSR
initialization program; and said TSR initialization program making an entry into said system IDT for said request to obtain said protected-mode interface, said entry including a vector to said code for processing said request to obtain a protected-mode interface stored in said allocated extended memory.
6. The method of claim 5, said detecting step comprising the steps of:
triggering said TSR initialization program when, at run time, said DOS extender calls said VCPI to request a protected-mode interface; and said TSR initialization program giving said DOS extender an entry point to said driver rather than an entry point to said VCPI.
7. The method of claim 6, said step of giving said DOS
extender an entry point to said driver comprising the steps of:
said driver saving a real-mode return address for said DOS
extender into said shared data space;
said driver changing the real-mode return address to a new return address;
said driver passing control to said VCPI for default handling upon receipt, at run time, of said request from said DOS
extender to obtain said protected-mode interface;

upon completion of said default handling of said request to obtain said protected-mode interface by said VCPI, control passing to said TSR initialization program, via said new return address, to give said DOS extender said entry point to said driver; and said TSR initialization program making page table entries in a page table of said DOS extender so that said driver is valid within the protected mode context of said DOS extender.
8. The method of claim 7, said step of giving said DOS
extender an entry point to said driver comprising the steps of:
said TSR initialization program updating said plurality of selectors and said VCPI entry point offset with values passed back from said VCPI to said DOS extender into said shared data space upon default processing of said request for said protected-mode interface;
altering said VCPI entry point offset to an offset for said driver for a VCPI far call communications intercept; and returning control to the real mode return address saved in said shared data space.
9. The method of claim 1, wherein said predetermined interrupt is a non-maskable interrupt which is generated when said application attempts to address a predetermined address related to the device to be emulated.
10. A system which provides device virtualization to an application running under a DOS extender in a DOS-based operating system environment of a processor, said DOS extender executing within a protected-mode context created for said DOS extender within said DOS-based operating system environment of said processor at run-time, said protected-mode context created for said DOS extender including an interrupt descriptor table for said DOS extender (DOS extender IDT), said system comprising:
device emulation code stored at a predetermined address in a memory accessible to said processor;
a detection program which detects startup of said DOS
extender; and a driver which operates in said protected-mode context of said DOS extender and which, upon detection of startup of said DOS
extender by said detection program, patches said DOS extender IDT to include a vector to said device emulation code for a predetermined interrupt, whereby, when said processor detects said predetermined interrupt during execution of said application, said processor references said vector to said device emulation code patched into said DOS extender IDT by said driver.
11. The system of claim 10, wherein said predetermined address is in extended memory addressable by said processor, and said device emulation code is stored at said predetermined address at boot-time.
12. The system of claim 10, wherein said DOS-based operating system environment includes a virtual control program interface (VCPI) through which said DOS extender acquires said protected-mode context, and said detection program is a terminate-and-stay-resident (TSR) program which intercepts communications between said DOS extender and said VCPI during said execution of said application, said detection program detecting startup of said DOS extender when a communication from said DOS extender to said VCPI is a request to obtain a protected-mode interface.
13. The system of claim 12, wherein said driver includes code which (1) receives, at run-time, protected-mode far calls redirected by said TSR program from the DOS extender, (2) enters at least said vector into said DOS extender IDT, and (3) passes control to said VCPI.
14. The system of claim 13, wherein said driver further includes an interrupt handler which reflects said request for a protected-mode interface to said TSR program.
15. The system of claim 13, wherein said driver installs its interrupt vectors into the DOS extender IDT upon receipt of said protected-mode far calls redirected by said TSR program from said DOS
extender to said VCPI, said interrupt vectors including said vector to said device emulation code for said predetermined interrupt, thereby making said device emulation code available to said DOS extender and said application in said protected-mode context of said DOS extender.
16. The system of claim 12, said TSR program is triggered when, at run time, said DOS extender calls said VCPI to request a protected-mode interface, and said TSR program gives said DOS extender an entry point to said driver rather than an entry point to said VCPI.
17. The system of claim 10, wherein said predetermined interrupt is a non-maskable interrupt which is generated when said application attempts to address a predetermined address related to the device to be emulated.
CA002265567A 1996-09-11 1997-09-08 A method and system for device virtualization based on an interrupt request in a dos-based environment Expired - Fee Related CA2265567C (en)

Applications Claiming Priority (3)

Application Number Priority Date Filing Date Title
US08/712,363 US5790837A (en) 1996-09-11 1996-09-11 Method and system for device virtualization based on an interrupt request in a dos-based environment
US08/712,363 1996-09-11
PCT/US1997/015813 WO1998011489A1 (en) 1996-09-11 1997-09-08 A method and system for device virtualization based on an interrupt request in a dos-based environment

Publications (2)

Publication Number Publication Date
CA2265567A1 CA2265567A1 (en) 1998-03-19
CA2265567C true CA2265567C (en) 2001-04-24

Family

ID=24861801

Family Applications (1)

Application Number Title Priority Date Filing Date
CA002265567A Expired - Fee Related CA2265567C (en) 1996-09-11 1997-09-08 A method and system for device virtualization based on an interrupt request in a dos-based environment

Country Status (7)

Country Link
US (1) US5790837A (en)
EP (1) EP1019834A4 (en)
AU (1) AU718803B2 (en)
CA (1) CA2265567C (en)
MY (1) MY133787A (en)
TW (1) TW344814B (en)
WO (1) WO1998011489A1 (en)

Families Citing this family (3)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US6804232B1 (en) 2000-03-27 2004-10-12 Bbnt Solutions Llc Personal area network with automatic attachment and detachment
US7188347B2 (en) * 2002-05-24 2007-03-06 Nokia Corporation Method, apparatus and system for connecting system-level functionality of domestic OS of a mobile phone to any application operating system
US7827558B2 (en) 2004-06-30 2010-11-02 Devicevm, Inc. Mechanism for enabling a program to be executed while the execution of an operating system is suspended

Family Cites Families (5)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US4926322A (en) * 1987-08-03 1990-05-15 Compag Computer Corporation Software emulation of bank-switched memory using a virtual DOS monitor and paged memory management
US5303378A (en) * 1991-05-21 1994-04-12 Compaq Computer Corporation Reentrant protected mode kernel using virtual 8086 mode interrupt service routines
US5293590A (en) * 1992-04-06 1994-03-08 International Business Machines Corp. Personal computer with interface controller
US5390332A (en) * 1992-09-15 1995-02-14 Sun Microsystems, Inc. Method and apparatus for performing a takeover of a microprocessor
US5459869A (en) * 1994-02-17 1995-10-17 Spilo; Michael L. Method for providing protected mode services for device drivers and other resident software

Also Published As

Publication number Publication date
TW344814B (en) 1998-11-11
MY133787A (en) 2007-11-30
US5790837A (en) 1998-08-04
EP1019834A1 (en) 2000-07-19
WO1998011489A1 (en) 1998-03-19
AU718803B2 (en) 2000-04-20
AU4257997A (en) 1998-04-02
EP1019834A4 (en) 2000-09-20
CA2265567A1 (en) 1998-03-19

Similar Documents

Publication Publication Date Title
US11681639B2 (en) Direct access to a hardware device for virtual machines of a virtualized computer system
US7275028B2 (en) System and method for the logical substitution of processor control in an emulated computing environment
Chiueh et al. A survey on virtualization technologies
US8572604B2 (en) Method and apparatus to support virtualization with code patches
WO1999030241A9 (en) A method and system for device virtualization based on an interrupt request in a dos-based environment
US7272831B2 (en) Method and apparatus for constructing host processor soft devices independent of the host processor operating system
US6363409B1 (en) Automatic client/server translation and execution of non-native applications
US5953516A (en) Method and apparatus for emulating a peripheral device to allow device driver development before availability of the peripheral device
US8001543B2 (en) Direct-memory access between input/output device and physical memory within virtual machine environment
EP1524596B1 (en) Systems and methods for using synthetic instructions in a virtual machine
US20070078891A1 (en) Operating systems
US7877747B2 (en) Flexible operating system operable as either native or as virtualized
KR20160111996A (en) Co-designed dynamic language accelerator for a processor
EP0588473B1 (en) Method and apparatus for emulating the environment of a microprocessor
Hazzah Writing Windows VxDs and Device Drivers
CA2265567C (en) A method and system for device virtualization based on an interrupt request in a dos-based environment
EP1410170B1 (en) Logical substitution of processor control in an emulated computing environment
CN113312141A (en) Virtual serial port for virtual machines
Suann Zircon on seL4
Martinsen Implementation of Intel virtual machine extension root operation on the NPS least privilege separation kernel
Schilli Legacy Processor and Device Support for Fully Virtualized Systems
Poess Feasibility Study of Building a User-mode Native Windows NT VMM
KERNEL Jayce Martinsen September 2010 Thesis Advisor: Cynthia Irvine Second Reader: David Shifflett

Legal Events

Date Code Title Description
EEER Examination request
MKLA Lapsed