Next, you must rewrite each system-dependent procedure you created during the encapsulation stage to conform to the OS/2 protected-mode API. In contrast to MS-DOS functions, which are actuated through software interrupts and pass parameters in registers, OS/2 API functions are requested through a far call to a named entry point. Parameters are passed on the stack, along with the addresses of variables within the calling program's data segment that will receive any results returned by the function. The status of an operation is returned in register AX——zero if the function succeeded, an error code otherwise. All other registers are preserved.
Although it is not my intention here to provide a detailed introduction to OS/2 programming, Figure 16-3 illustrates the final form of our previous example, after conversion for OS/2. Note especially the addition of the extrn statement, the wlen variable, and the simulation of the MS-DOS function status. This code may not be elegant, but it serves the purpose of limiting the necessary changes to a very small portion of the source file. Some OS/2 functions (such as DosOpen) require parameters that have no counterpart under MS-DOS; you can usually select reasonable values for these extra parameters that will make their existence temporarily invisible to the remainder of the application.
stdin equ 0 ; standard input handle
stdout equ 1 ; standard output handle
stderr equ 2 ; standard error handle
extrn DosWrite:far
msg db 'This is a sample message'
msg_len equ $-msg
wlen dw ? ; receives actual number
; of bytes written
.
.
.
mov dx,seg msg ; DS:DX = message address
mov ds,dx
mov dx,offset DGROUP:msg
mov cx,msg_len ; CX = message length
mov bx,stdout ; BX = handle
call write ; perform the write
jc error ; jump if error
cmp ax,msg_len ; all characters written?
jne diskfull ; no, device is full
.
.
.
write proc near ; write to file or device
; call with:
; BX = handle
; CX = length of data
; DS:DX = address of data
; returns:
; if successful, carry clear
; and AX = bytes written
; if error, carry set
; and AX = error code
push bx ; handle
push ds ; address of data
push dx
push cx ; length of data
push ds ; receives length written
mov ax,offset DGROUP:wlen
push ax
call DosWrite ; transfer to OS/2
or ax,ax ; did write succeed?
jnz write1 ; jump, write failed
mov ax,wlen ; no error, OR cleared CY
ret ; and AX := bytes written
write1: stc ; write error, return CY set
ret ; and AX = error number
write endp
.
.
.
Figure 16-3. Code from Figure 16-2 after "conversion." The MS-DOS function call has been replaced with the equivalent OS/2 function call. Since the knowledge of the operating system has been hidden inside the subroutine by the previous encapsulation step, the surrounding program's requests for write operations should run unchanged. Note that the OS/2 function had to be declared as an external name with the "far" attribute, and that a variable named wlen was added to the data segment of the application to receive the actual number of bytes written.
Figures 16-4, 16-5, and 16-6 list the OS/2 services that are equivalent to selected MS-DOS and ROM BIOS Int 21H, Int 10H, and Int 16H calls. MS-DOS functions related to FCBs and PSPs are not included in these tables because OS/2 does not support either of these structures. The MS-DOS terminate-and-stay-resident functions are also omitted. Because OS/2 is a true multitasking system, a process doesn't need to terminate in order to stay resident while another process is running.
MS-DOS Description OS/2 function
Int 21H Function
0 Terminate process DosExit
1 Character input with echo KbdCharIn
2 Character output VioWrtTTY
3 Auxiliary input DosRead
4 Auxiliary output DosWrite
5 Printer output DosWrite
6 Direct console I/O KbdCharIn,
VioWrtTTY
7 Unfiltered input without echo KbdCharIn
8 Character input without echo KbdCharIn
9 Display string VioWrtTTY
0AH (10) Buffered keyboard input KbdStringIn
0BH (11) Check input status KbdPeek
0CH (12) Reset buffer and input KbdFlushBuffer,
KbdCharIn
0DH (13) Disk reset DosBufReset
0EH (14) Select disk DosSelectDisk
19H (25) Get current disk DosQCurDisk
1BH (27) Get default drive data DosQFSInfo
1CH (28) Get drive data DosQFSInfo
2AH (42) Get date DosGetDateTime
2BH (43) Set date DosSetDateTime
2CH (44) Get time DosGetDateTime
2DH (45) Set time DosSetDateTime
2EH (46) Set verify flag DosSetVerify
30H (48) Get MS-DOS version DosGetVersion
36H (54) Get drive allocation DosQFSInfo
information
38H (56) Get or set country DosGetCtryInfo
information
39H (57) Create directory DosMkdir
3AH (58) Delete directory DosRmdir
3BH (59) Set current directory DosChdir
3CH (60) Create file DosOpen
3DH (61) Open file DosOpen
3EH (62) Close file DosClose
3FH (63) Read file or device DosRead
40H (64) Write file or device DosWrite
41H (65) Delete file DosDelete
42H (66) Set file pointer DosChgFilePtr
43H (67) Get or set file attributes DosQFileMode,
DosSetFileMode
44H (68) I/O control (IOCTL) DosDevIOCtl
45H (69) Duplicate handle DosDupHandle
46H (70) Redirect handle DosDupHandle
47H (71) Get current directory DosQCurDir
48H (72) Allocate memory block DosAllocSeg
49H (73) Release memory block DosFreeSeg
4AH (74) Resize memory block DosReAllocSeg
4BH (75) Execute program DosExecPgm
4CH (76) Terminate process with DosExit
return code
4DH (77) Get return code DosCWait
4EH (78) Find first file DosFindFirst
4FH (79) Find next file DosFindNext
54H (84) Get verify flag DosQVerify
56H (86) Rename file DosMove
57H (87) Get or set file date and time DosQFileInfo,
DosSetFileInfo
59H (89) Get extended error DosErrClass
information
5BH (91) Create new file DosOpen
5CH (92) Lock or unlock file region DosFileLocks
65H (101) Get extended country DosGetCtryInfo
information
66H (102) Get or set code page DosGetCp,
DosSetCp
67H (103) Set handle count DosSetMaxFH
68H (104) Commit file DosBufReset
6CH (108) Extended open file DosOpen
Figure 16-4. Table of selected MS-DOS function calls and their OS/2 counterparts. Note that OS/2 functions are typically more powerful and flexible than the corresponding MS-DOS functions, and that this is not a complete list of OS/2 services.
ROM BIOS Description OS/2 function
Int 10H Function
0 Select display mode VioSetMode
1 Set cursor type VioSetCurType
2 Set cursor position VioSetCurPos
3 Get cursor position VioGetCurPos
6 Initialize or scroll window up VioScrollUp
7 Initialize or scroll window down VioScrollDn
8 Read character and attribute VioReadCellStr
9 Write character and attribute VioWrtNCell
0AH (10) Write character VioWrtNChar
0EH (14) Write character in teletype mode VioWrtTTY
0FH (15) Get display mode VioGetMode
10H (16) Set palette, border color, etc. VioSetState
13H (19) Write string in teletype mode VioWrtTTY
Figure 16-5. Table of ROM BIOS Int 10H video-display driver functions used by MS-DOS applications and their OS/2 equivalents. This is not a complete list of OS/2 video services.
ROM BIOS Description OS/2 function
Int 16H Function
0 Read keyboard character KbdCharIn
1 Get keyboard status KbdPeek
2 Get keyboard flags KbdGetStatus
Figure 16-6. Table of ROM BIOS Int 16H keyboard driver functions used by MS-DOS applications and their OS/2 equivalents. This is not a complete list of OS/2 keyboard services.