home *** CD-ROM | disk | FTP | other *** search
- PAGE 60,131
- TITLE GENERIC Device Driver devhlp interface
- ;
- ;┌───────────────────────────────────────────────────────────────────────────┐
- ;│ │
- ;│ GENERIC Device Driver DEVHLP Interface │
- ;│ │
- ;│ _dev_help - calls OS/2 DevHlp function by doing a far call to the value │
- ;│ stored in dev_hlpCS. This is the one to use generally. │
- ;│ The general operation is to copy all the parameters passed │
- ;│ in the input structure by the caller onto the stack and │
- ;│ then pop them into the registers. Then, dev_hlp is called │
- ;│ by referring to the one in our CODE segment. This lets us │
- ;│ use DS and ES to hold all sorts of values. After we │
- ;│ (hopefully) get back from dev_hlp, we store the register and │
- ;│ flag values in the output structure and return to the caller │
- ;│ │
- ;│ _dev_help1 - Same as above, except it uses the value of del_hlp stored in │
- ;│ our data segment and points to it with ES. This one is │
- ;│ intended to be used only until dev_hlpCS has the right value,│
- ;│ very soon after INIT starts. It is used by those functions │
- ;│ to get the right value in dev_hlpCS. It is in a segment that│
- ;│ is discarded after INIT is done, so it is not accessable by │
- ;│ other functions. │
- ;│ │
- ;└───────────────────────────────────────────────────────────────────────────┘
- ;
- .286P ; Must use 286 mode if OS/2
- PAGE
- ;┌───────────────────────────────────────────────────────────────────────────┐
- ;│ STRUCTURE DEFINITIONS │
- ;└───────────────────────────────────────────────────────────────────────────┘
- ;
- regs struc
- r_ax dw ? ; AX value
- r_bx dw ? ; BX
- r_cx dw ? ; CX
- r_dx dw ? ; DX
- r_si dw ? ; SI
- r_di dw ? ; DI
- r_es dw ? ; ES
- r_ds dw ? ; DS
- r_cs dw ? ; CS
- r_flags dw ? ; FLAGS
- r_es_valid db ? ; Indicator if ES is valid
- r_ds_valid db ? ; Indicator if DS is valid
- regs ends
- ;
- ;┌───────────────────────────────────────────────────────────────────────────┐
- ;│ CONSTANT DEFINITIONS │
- ;└───────────────────────────────────────────────────────────────────────────┘
- ;
- TRUE equ 1 ; Boolean values
- FALSE equ 0
- ;
- ;
- NULL SEGMENT WORD PUBLIC 'BEGDATA'
- extrn _devhlp:dword
- NULL ENDS
- PAGE
- ;
- ;┌───────────────────────────────────────────────────────────────────────────┐
- ;│ CODE SEGMENT │
- ;└───────────────────────────────────────────────────────────────────────────┘
- ;
- MAINSEG SEGMENT WORD PUBLIC 'CODE'
- ;
- ASSUME CS:MAINSEG
- public _dev_help
- public _dev_hlpCS
- ;
- ;┌───────────────────────────────────────────────────────────────────────────┐
- ;│ │
- ;│ dev_help - function to call OS/2 DevHlp facility. │
- ;│ │
- ;│ struct regs { │
- ;│ unsigned AX,BX,CX,DX,SI,DI,ES,flags; │
- ;│ boolean es_valid; │
- ;│ boolean ds_valid; │
- ;│ } │
- ;│ │
- ;│ Syntax - unsigned dev_helper(far ptr *in_regs, far ptr *out_regs); │
- ;│ │
- ;└───────────────────────────────────────────────────────────────────────────┘
- ;
- _dev_hlpCS dd 0
- _dev_help proc far
- ;
- ; Point to current frame
- ; This gets BP pointing generally at the parameters passed to us by the caller
- ;
- push bp
- mov bp,sp
- ;
- ; Save entry regs - we are gonna step on them hard
- ;
- push ax
- push bx
- push cx
- push dx
- push si
- push di
- push es
- pushf
- push ds
- ;
- ; Load stack with values to go into registers
- ;
- ; First one is DS. If the ds_valid flag in the in_regs struc passed by the
- ; caller is TRUE, use the value in the in_regs struc. If it is FALSE, use
- ; the current value of DS.
- ;
- les bx,[bp+6]
- cmp es:[bx].r_ds_valid,TRUE
- jnz devh1001
- mov ax,es:[bx].r_ds
- push ax
- jmp devh2001
- devh1001:
- push ds
- ;
- devh2001:
- ;
- ; Next is ES. Same bit of logic with the es_valid flag, use the struc value
- ; if es_valid is TRUE, otherwise, use the value in the ES register.
- ;
- les bx,[bp+6]
- cmp es:[bx].r_es_valid,TRUE
- jnz devh3001
- mov ax,es:[bx].r_es
- push ax
- jmp devh4001
- devh3001:
- push es
- ;
- devh4001:
- ;
- ; Now for the rest of the registers. They are removed from the struc and
- ; pushed onto the stack in the following order: AX, BX, CX, DX, SI, and DI
- ;
- mov ax,es:[bx].r_ax
- push ax
- mov ax,es:[bx].r_bx
- push ax
- mov ax,es:[bx].r_cx
- push ax
- mov ax,es:[bx].r_dx
- push ax
- mov ax,es:[bx].r_si
- push ax
- mov ax,es:[bx].r_di
- push ax
- ;
- ; Now pop the values off the stack and into the proper registers
- ;
- pop di
- pop si
- pop dx
- pop cx
- pop bx
- pop ax
- pop es
- pop ds
- ;
- ; call OS/2 DevHlp
- ;
- call cs:_dev_hlpCS
- ;
- ; Save return values in output structure. The first thing to do is to save
- ; DS and BX because that is what we are going to use to point to the struc.
- ; We save the flags too, 'cause we don't want 'em touched by these operations.
- ;
- push ds
- pushf
- push bx
- ;
- ; Now, load DS:BX to point to the output struc given to us by the caller.
- ;
- lds bx,[bp+10]
- ;
- ; Store AX into the return struc
- ;
- mov [bx].r_ax,ax
- ;
- ; Next, is BX (use the value in the stack)
- ;
- pop ax
- mov [bx].r_bx,ax
- ;
- ; Then the flags, also on the stack
- ;
- pop ax
- mov [bx].r_flags,ax
- ;
- ; and DS from the stack.
- ;
- pop ax
- mov [bx].r_ds,ax
- ;
- ; ES. But we need to move it to a general register, as we cannot move ES to
- ; memory directly (the CPU won't do it). So, we push ES onto the stack and
- ; pop it into AX, then move AX to the struc.
- ;
- push es
- pop ax
- mov [bx].r_es,ax
- ;
- ; Now the rest of the registers. We can move them straight from the register
- ; to the struc as we have not touched them since we returned from DevHlp.
- ;
- mov [bx].r_cx,cx
- mov [bx].r_dx,dx
- mov [bx].r_di,di
- mov [bx].r_si,si
- ;
- ; And finally, set both es_valid and ds_valid to TRUE cause they are silly
- ;
- mov [bx].r_es_valid,TRUE
- mov [bx].r_ds_valid,TRUE
- ;
- ; Restore entry regs
- ;
- pop ds
- popf
- pop es
- pop di
- pop si
- pop dx
- pop cx
- pop bx
- pop ax
- ;
- ; Return to caller
- ;
- pop bp
- ret
- ;
- _dev_help endp
- MAINSEG ENDS
- ;
- INITSEG SEGMENT WORD PUBLIC 'CODE'
- ;
- ASSUME CS:INITSEG
- public _dev_help1
- ;
- ;┌───────────────────────────────────────────────────────────────────────────┐
- ;│ │
- ;│ dev_help1 - function to call OS/2 DevHlp facility. │
- ;│ │
- ;│ struct regs { │
- ;│ unsigned AX,BX,CX,DX,SI,DI,ES,flags; │
- ;│ boolean es_valid; │
- ;│ boolean ds_valid; │
- ;│ } │
- ;│ │
- ;│ Syntax - unsigned dev_helper(far ptr *in_regs, far ptr *out_regs); │
- ;│ │
- ;│ This one is used at init time until dev_hlpCS is initialized. After │
- ;│ INIT, this one is gone as it is in a segment that is discarded after │
- ;│ initialization is finished. │
- ;│ │
- ;└───────────────────────────────────────────────────────────────────────────┘
- ;
- _dev_help1 proc far
- ;
- ; Point to current frame
- ;
- push bp
- mov bp,sp
- ;
- ; Save entry regs
- ;
- push ax
- push bx
- push cx
- push dx
- push si
- push di
- push es
- pushf
- push ds
- push ds
- ;
- ; Load stack with values to go into registers
- ;
- les bx,[bp+6]
- cmp es:[bx].r_ds_valid,TRUE
- jnz devh1000
- mov ax,es:[bx].r_ds
- push ax
- jmp devh2000
- devh1000:
- push ds
- ;
- devh2000:
- ;
- mov ax,es:[bx].r_ax
- push ax
- mov ax,es:[bx].r_bx
- push ax
- mov ax,es:[bx].r_cx
- push ax
- mov ax,es:[bx].r_dx
- push ax
- mov ax,es:[bx].r_si
- push ax
- mov ax,es:[bx].r_di
- push ax
- ;
- ; load registers from the stack
- ;
- pop di
- pop si
- pop dx
- pop cx
- pop bx
- pop ax
- pop ds
- pop es
- ;
- ; call OS/2 DevHlp
- ;
- call es:_devhlp
- ;
- ; Save return values in output structure
- ;
- push ds
- pushf
- push bx
- lds bx,[bp+10]
- mov [bx].r_ax,ax
- pop ax
- mov [bx].r_bx,ax
- pop ax
- mov [bx].r_flags,ax
- pop ax
- mov [bx].r_ds,ax
- push es
- pop ax
- mov [bx].r_es,ax
- mov [bx].r_cx,cx
- mov [bx].r_dx,dx
- mov [bx].r_di,di
- mov [bx].r_si,si
- mov [bx].r_es_valid,TRUE
- mov [bx].r_ds_valid,TRUE
- ;
- ; Restore entry regs
- ;
- pop ds
- popf
- pop es
- pop di
- pop si
- pop dx
- pop cx
- pop bx
- pop ax
- ;
- ; Return to caller
- ;
- pop bp
- ret
- ;
- _dev_help1 endp
- PAGE
- INITSEG ENDS
- ;
- END