Opsys provides multi-tasking and other primitive services to GO.EXE on top of MS-DOS services. It originated in 1983 on the Epson QX10 (a 64Kbyte RAM micro-computer with two 5ΒΌ" floppy disc drives), entirely bypassing the built-in CP/M operating system. By 1989 migration to MS-DOS could no longer be avoided, if only to take advantage of advances in storage technology. Opsys for MS-DOS represents something of a compromise from the multi-tasking viewpoint, as MS-DOS services are used to access all devices other than the screen, the keyboard and the serial and parallel ports.
Opsys is a library of Personal Computer subroutines which may be combined into Assembler Language programs with the MS-DOS LINK command. The subroutines assist with data conversion, screen handling, keyboard and mouse, printing, serial communication, file access and multi-tasking.
Each task has its own Stack Segment (capacity 192 pushes) with a Task Control Area at SS:0. When a task is handed execution from the Task Scheduler, the Direction Flag is CLEAR (UPWARDS) and register BP is CLEAR (0). These values should be present when calling any Opsys library subroutine. The Task Scheduler never pre-empts execution: the executing task must block itself by calling OPSYS or by waiting on an Event, or terminate itself by executing a RET instruction with the SP register at its initial value.
A Session is a group of tasks sharing the same virtual screen and keyboard cursor. Only one virtual screen appears (with cursor) on the physical screen: the user selects this Foreground Session by pressing Alt+Fn where n is the Session number. Spawned tasks belong to the same session as the spawning task except when the new task commences at offset SESSION, which creates a new session. Each task has a rectangular Window occupying all or part of its virtual screen (task windows may overlap). If a task terminates, its stack and task number may be reallocated; session numbers are not reallocated even if all their tasks are terminated.
INCLUDE OPSYS.INC
EXTERN MENU:near
.CODE
.STARTUP
call opsys
mov cx,OFFSET menu
mov di,OFFSET session
call spawn
jmp taskm
END
In the above MASM program, the call to OPSYS activates the multi-tasking environment; on return the remaining code is executed by Task 1 (in Session 1). The call to SPAWN creates Task 2, which will execute from OFFSET session but not until Task 1 blocks. Task 1 could block voluntarily by calling OPSYS again, which would allow Task 2 to run immediately, but instead it passes execution to the code at OFFSET taskm, which is the Terminal Emulator provided by Opsys. In due course, the Terminal Emulator will block when it calls the GET subroutine to await data at its serial port.
Task 2's code at OFFSET session creates Session 2 (because it needs a separate virtual screen from the Terminal Emulator) then executes application code from OFFSET menu, perhaps to display a menu selection on its virtual screen (which will be in the background until the hotkey Alt+F2 is pressed). Very likely, Task 2 will block by calling the CHAR subroutine to await keyboard entry and there will be no task ready to run, so Opsys halts pending an interrupt.
To make this scheme work, the initial invocation of OPSYS creates the (hidden) System Task, Task 0, which receives keyboard and mouse events. Task 0 handles hotkeys and delivers keystrokes to the task currently in the foreground.
Further tasks may be created by calling SPAWN. For example, to support full-duplex operation the Terminal Emulator spawns another task to send keyboard data out through its Serial Port, so we have already ended up with four tasks (in GO.EXE press the hotkey Alt+M to pop-up a box showing how many tasks are activated).
Tasks may use MS-DOS services via INT 21h etc. but task scheduling is not possible during the execution of such services.
Opsys is shut down by pressing the hotkey Alt+X. Execution returns to MS-DOS.